展开式弹出窗口

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

使用隐藏的复选框/单选按钮、:checked 伪类选择器和相邻兄弟 (~) 组合器的技巧,确实可以通过纯 CSS1 实现了某些简洁的功能可能性。如果您需要入门指南,我们最近使用此方法 构建了一个功能性选项卡区域

让我们再次利用它来构建“展开式弹出窗口”。也就是说,您可以**点击**链接/按钮以显示类似工具提示的丰富 HTML 弹出内容。

查看演示   下载文件

HTML 结构

我们需要一个复选框来实现开启/关闭的可点击功能(不用担心,它是隐藏的)。然后紧随其后的是一个标签。像任何好的标签一样,for 属性与输入的 id 属性匹配。这样我们就可以点击它来切换复选框。

标签在其内部包含多个 span 元素。.box span 是丰富 HTML 弹出窗口的容器。换句话说,您可以将任何内容放在其中。好吧,任何您想要作为内联元素的内容。使用 div 和标题标签等元素很诱人,但某些浏览器不兼容,会将这些元素渲染在标签外部而不是内部。将 .box 放在标签外部并不是什么大问题,因为我们可以链接 ~ 选择器来使其隐藏/显示,但将它们放在内部意味着我们可以相对于标签的位置定位弹出窗口,就像“弹出窗口”应该做的那样。

<input type="checkbox" id="popup" class="popUpControl">
<label for="popup">
   Click me!
   <span class="box">
       Super cool popup content
   </span>
</label> 

CSS 基础

我们对 .box 的目标是将其相对于其所在的标签进行绝对定位,以便它弹出并附加到标签上。默认情况下,它将通过设置为零的不透明度而隐藏。我们还将将其缩放到零、倾斜并添加过渡。然后,当我们通过复选框被选中来显示它时,我们将将其放大,移除倾斜,并通过将不透明度恢复到 1 来使其可见。

.box {
	position: absolute;
	left: 0;
	top: 100%;
	z-index: 100;
	
	/* Prevent some white flashing in Safari 5.1 */
	-webkit-backface-visibility: hidden;

	-moz-border-radius:    20px; 
	-webkit-border-radius: 20px; 
	border-radius:         20px; 
	
	width: 260px; 
	padding: 20px;
	opacity: 0;
			    
	-webkit-transform: scale(0) skew(50deg);
	-moz-transform:    scale(0) skew(50deg);
	-ms-transform:     scale(0) skew(50deg);
	-o-transform:      scale(0) skew(50deg);
	
	-webkit-transform-origin: 0px -30px;
	-moz-transform-origin:    0px -30px;
	-ms-transform-origin:     0px -30px;
	-o-transform-origin:      0px -30px;
	
	-webkit-transition: -webkit-transform ease-out .35s, opacity ease-out .4s;
	-moz-transition:    -moz-transform    ease-out .35s, opacity ease-out .4s;
	-ms-transition:     -ms-transform     ease-out .35s, opacity ease-out .4s;
	-o-transition:      -o-transform      ease-out .35s, opacity ease-out .4s;
}

.popUpControl { 
	display: none; 
}
.popUpControl:checked ~ label > .box {
	opacity: 1;
	-webkit-transform: scale(1) skew(0deg);
	-moz-transform:    scale(1) skew(0deg);
	-ms-transform:     scale(1) skew(0deg);
	-o-transform:      scale(1) skew(0deg);
}

box 的实际 CSS 有一些额外的样式,但这是重要的功能性内容。获取随本教程提供的下载以获取完整的 CSS 集。

打开时更改按钮文本

这对于这里的想法来说并不重要,但此演示中的另一个巧妙技巧是在弹出窗口打开时更改按钮的文本。这是通过在 :checked 时实际隐藏按钮内的文本并插入新文本来实现的。基础知识

<input type="checkbox">
<label>
   <span>Default text</span>
</label>
[type=checkbox]:checked ~ label span { 
   display: none; 
}
[type=checkbox]:checked ~ label:before { 
   content: "Text to show when checked";
}

另一个“技巧”(不好,因为生成的 content 可访问性不高 或不可选择)。但是,嘿,我们仍然玩得很开心,对吧?

1 是的,但是……JavaScript

这绝对是“关注点分离”的界限。即使我是在“纯”CSS 中创建的,但我实际上认为这种类型的行为可能更适合 JavaScript。而“使用 JavaScript”是指我实际上会怎么做

  1. 为 .box 切换“打开”和“关闭”的类名,而不是使用复选框。
  2. 通过 JavaScript 更改文本,而不是使用 CSS 生成的内容。

但其他所有内容都应该保留在 CSS 中。样式、过渡、转换……这些都是样式,而不是功能。

哇,我真是个伪君子,哈哈?

致谢

感谢 Victor Coulon 向我发送了 这个想法,我以此为基础进行了改进。