通常在实现 Modal 组件时,我会使用 js 来控制隐藏与显示的状态。最近在看 Daisy UI 的时候,发现是用纯 css 实现,没有一句 js 代码,好奇心驱使我研究一下其原理。
方法一:使用锚点
我们知道 HTML 的<a>
标签可以通过href
属性创建超链接,填入类似#modal
便可以跳转到同一页面对应的锚点位置。
css 中有一个:target
伪类选择器。当我们访问的地址加上对应的锚点时,对应的:target
伪类就会生效。假设我们的地址为 http://example.com ,那么当点击上面的<a>
标签的时候,页面地址会变成 http://example.com#modal ,此时:target
伪类生效,modal 就会显示。
让 modal 元素本身 display: none
,给它的 :target
设置display: block
,就可以实现 modal 的隐藏与显示。
<a href="#modal">Open modal using label + checkbox</a>
<div class="modal" id="modal">
<h1>Modal</h1>
<a href="#">close</a>
</div>
// 核心样式,省略了无关样式
.modal {
display: none;
}
.modal:target {
display: block;
}
方法二:使用 label + checkbox
锚点方法有个问题,就是改变了 url 的 hash值,会插入一条历史纪录,影响返回。
HTML 的<input>
标签里有个checkbox
类型,拥有两种状态,恰好适合控制 modal 的开关。
css 里可以用:checked
选择器来编写选中时的样式,把 modal 元素放在 checkbox 之后,利用兄弟选择器+
,设置 modal 的display
属性,即可实现 modal 的隐藏与显示。
checkbox 存在默认样式,所以可以用<label>
标签的for
属性绑定 checkbox,这样就能随意定义样式,也不受摆放位置的限制了。
<label for="modal2">Open modal using anchor link</label>
<input type="checkbox" id="modal2" class="checkbox" />
<div class="modal">
<h1>Modal</h1>
<label for="modal2">close</label>
</div>
// 核心样式,省略了无关样式
.modal {
display: none;
}
.checkbox:checked + .modal {
display: block;
}
就这样我们封装好了一个 Modal 组件。效果如下(若不能运行请在新窗口打开):