在网页中我们经常会用到模态框,一般会用于显示表单或者是提示信息。由于模态框涉及到页面上比较多的交互效果,最简单的交互就是打开以及关闭两个操作,而关闭又会涉及是否需要在打开状态下点击模态框外部能够关闭这样的功能,因为这些交互问题,所以一般都会首先考虑到使用JavaScript实现。但是我们也可以使用纯CSS来实现。
实现思路:
使用HTML中checkbox类型的input标签
使用label来切换checkbox的选中状态
使用css中的:checked伪类选择器根据checkbox是否被选中切换页面元素的样式
使用css的属性选择器来添加多功能开关
开始实现:
首先我们先写出基本结构
HTML
<div id="modal" class="modal__wrapper">
<div class="modal">
<div class="modal__main">
<p> 模态框内容 </p>
</div>
</div>
</div>
CSS:
.modal {
width: 50%;
height: 50vh;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 2;
background: #ffffff;
}
.modal__body {
padding: 3rem 1rem;
}
.modal-overlay {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
padding: 0;
background-color: rgba(43, 46, 56, 0.9);
z-index: 1;
}
现在我们能够看到模态主体部分以及背景蒙版的样式了。
接下来让我们给这个模态框添加开关
将HTML改为:
<div id="modal" class="modal__wrapper">
<input id="modal__state" class="modal__state" type="checkbox">
<label class="modal__toggle modal__toggle--outside" for="modal__state">打开模态框</label>
<div class="modal">
<div class="modal__body">
<p> 模态框内 </p>
</div>
</div>
<div class="modal-overlay"></div>
</div>
将模态框的初始状态改为隐藏,并在checkbox选中时显示
.modal {
width: 50%;
height: 50vh;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 2;
background: #ffffff;
display: none;
}
.modal__body {
padding: 3rem 1rem;
}
.modal-overlay {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
padding: 0;
background-color: rgba(43, 46, 56, 0.9);
z-index: 1;
display: none;
}
.modal__state:checked + label{
display: none;
}
.modal__state:checked + label + .modal,
.modal__state:checked + label + .modal + .modal-overlay{
display: block;
}
目前我们可以实现点击复选框打开模态框了,但是打开之后我们关闭不了,所以我们需要让打开的弹框可以关闭,接下来只需要做一件事情,就是在打开的模态框中再添加一个label,如:
HTML
<div id="modal" class="modal__wrapper">
<input id="modal__state" class="modal__state" type="checkbox">
<label class="modal__toggle modal__toggle--outside" for="modal__state">打开模态框</label>
<div class="modal">
<div class="modal__body">
<label class="modal__toggle modal__toggle--outside" for="modal__state">关闭模态框</label>
<p> 模态框内 </p>
</div>
</div>
<div class="modal-overlay"></div>
</div>
这样基本的打开以及关闭模态框的交互就完成了,让我们再简单优化一下样式,使其看起来至少美观一些
CSS
.modal {
width: 50%;
height: 50vh;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 2;
background: #fff;
display: none;
}
.modal__body {
padding: 3rem 1rem;
}
.modal-overlay {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
padding: 0;
background-color: rgba(43, 46, 56, 0.9);
z-index: 1;
display: none;
}
.modal__state:checked + label{
display: none;
}
.modal__state:checked + label + .modal,
.modal__state:checked + label + .modal + .modal-overlay{
display: block;
}
.modal__state{
position: fixed;
top: -9999px;
}
.modal__wrapper .modal__toggle {
padding: 1rem;
display: inline-block;
margin-top: -1rem;
margin-right: -1rem;
color: black;
}
.modal__wrapper .modal__toggle--outside {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin-top: 1rem;
background: #df2f2f;
cursor: pointer;
}
.modal__wrapper .modal__toggle--inside {
float: right;
font-size: 4rem;
width: 2rem;
height: 2rem;
text-align: center;
cursor: pointer;
transition: 0.15s;
margin-top: -3.5rem;
margin-right: -2rem;
}
现在我们的模态框看起来就美观多了
目前已经实现了打开和关闭的切换,那么如何实现点击模块框外面关闭模态框呢?可能这部分看起来比较复杂一些,但是其实也非常的简单。默认状态下我们显示的是由一个DIV实现的蒙层,但是如果我们将DIV也换成一个label呢?那应该就跟关闭按钮的逻辑一样了。
另外,为了使得我们的模块框能够适应点击模块框外部关闭或者不关闭两种情况,我们还可以利用css的属性选择器来实现功能的开关。下面是我们最终的html和css。
HTML
<div id="modal" class="modal__wrapper" outside-close>
<input id="modal__state" class="modal__state" type="checkbox">
<label class="modal__toggle modal__toggle--outside" for="modal__state">打开模态框</label>
<div class="modal">
<div class="modal__body">
<label class="modal__toggle modal__toggle--outside" for="modal__state">关闭模态框</label>
<p> 模态框内 </p>
</div>
</div>
<div class="modal-overlay"></div>
</div>
CSS样式
.modal {
width: 50%;
height: 50vh;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 2;
background: #fff;
display: none;
}
.modal__body {
padding: 3rem 1rem;
}
.modal-overlay {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
padding: 0;
background-color: rgba(43, 46, 56, 0.9);
z-index: 1;
display: none;
}
.modal__state:checked + label{
display: none;
}
.modal__state:checked + label + .modal,
.modal__state:checked + label + .modal + .modal-overlay{
display: block;
}
.modal__state{
position: fixed;
top: -9999px;
}
.modal__wrapper .modal__toggle {
padding: 1rem;
display: inline-block;
margin-top: -1rem;
margin-right: -1rem;
color: black;
}
.modal__wrapper .modal__toggle--outside {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin-top: 1rem;
background: #df2f2f;
cursor: pointer;
}
.modal__wrapper .modal__toggle--inside {
float: right;
font-size: 4rem;
width: 2rem;
height: 2rem;
text-align: center;
cursor: pointer;
transition: 0.15s;
margin-top: -3.5rem;
margin-right: -2rem;
}
.modal__wrapper[outside-close] .modal__state:checked + label + .modal + .modal-overlay {
display: none;
}
.modal__wrapper[outside-close] .modal__state:checked + label.modal__toggle--outside{
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
padding: 0;
background-color: rgba(43, 46, 56, 0.9);
z-index: 1;
display: block;
transform: translate(0, 0);
margin-top: 0;
color: transparent;
}
现在的这种实现目前只适用于页面上只有一个模态框的情况,如果需要实现多个也是可能的,只需要做几个简单的改动即可实现。