效果预览
ps:懒得看的看官,可以直接去文末拷代码
首先了解一次 css选择器的[+]选择器,w3school的介绍选节如下:
选择器 | 例子 | 例子描述 |
---|---|---|
element+element | div+p | 选择紧接在 <div> 元素之后的所有 <p> 元素 |
:checked | input:checked | 选择每个被选中的 <input> 元素 |
[+]选择器可以选择到紧跟某元素<div />之后的兄弟节点, 而非<div />里的后代元素
[:checked]选择器, 可以说是针对<input />而存在的, 它匹配的是被选中的 input 元素
复选框html结构
<input id="switch" class="Dswitch" type="checkbox" />
<label for="switch"></label>
css主要样式
.Dswitch {
opacity: 0;
width: 0;
height: 0;
display: none;
}
.Dswitch+label {
position: relative;
display: inline-block;
top: 0px;
vertical-align: middle;
}
.Dswitch+label:after {
content: '';
outline: none;
width: 52px;
height: 31px;
position: relative;
border: 1px solid #dfdfdf;
background-color: #fdfdfd;
box-shadow: #dfdfdf 0 0 0 0 inset;
border-radius: 20px;
-moz-border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-clip: content-box;
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
user-select: none;
outline: none;
z-index: 1;
}
.Dswitch+label:before {
content: '';
width: 29px;
height: 29px;
position: absolute;
top: 2px;
left: 2px;
border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
z-index: 10;
}
.Dswitch:checked+label:after {
border-color: #64bd63;
box-shadow: #64bd63 0 0 0 16px inset;
background-color: #64bd63;
}
.Dswitch:checked+label:before {
left: 23px;
}
注:for 对应指定 id
原理分析
- 原生复选框有是否选择的功能, 利用原生复选框 <input type="checkbox" /> 支持这个功能
- <label /> 设置 for 值后,就算跟对应的 表单元素 不是包裹关系,也可以跟对应的 表单元素 绑定关联起来
- [:checked], [+] 两个选择器结合使用, 用[:checked]匹配被选中的表单, [:checked + label] 就能匹配到 选中表单后面的<label />元素了
- <label /> 元素利用 :before, :after 就可以设置对应的样式效果
动画优化
最后在.Dswitch-animbg{}里加合适的 transition 设置,就可以优化成动画效果
完整代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="renderer" content="webkit">
<meta name="referrer" content="always">
<title>漂亮的复选框</title>
<style>
.user-select-none {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.Dswitch {
opacity: 0;
width: 0;
height: 0;
display: none;
}
.Dswitch+label {
position: relative;
display: inline-block;
top: 0px;
vertical-align: middle;
}
.Dswitch+label:after {
content: '';
outline: none;
width: 52px;
height: 31px;
position: relative;
border: 1px solid #dfdfdf;
background-color: #fdfdfd;
box-shadow: #dfdfdf 0 0 0 0 inset;
border-radius: 20px;
-moz-border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-clip: content-box;
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
user-select: none;
outline: none;
z-index: 1;
}
.Dswitch+label:before {
content: '';
width: 29px;
height: 29px;
position: absolute;
top: 2px;
left: 2px;
border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
z-index: 10;
}
.Dswitch:checked+label:after {
border-color: #64bd63;
box-shadow: #64bd63 0 0 0 16px inset;
background-color: #64bd63;
}
.Dswitch:checked+label:before {
left: 23px;
}
.Dswitch-animbg+label:after {
transition: background-color ease 0.4s;
}
.Dswitch-animbg+label:before {
transition: left 0.3s;
}
.Dswitch-animbg:checked+label:after {
box-shadow: #dfdfdf 0 0 0 0 inset;
background-color: #64bd63;
transition: border-color 0.4s, background-color ease 0.4s;
}
.Dswitch-animbg:checked+label:before {
transition: left 0.3s;
}
</style>
</head>
<body>
<label class="user-select-none">
<span style="font-size: 16px;vertical-align: sub;">是否启用</span>
<input id="switchAnimbg" class="Dswitch Dswitch-animbg" type="checkbox" />
<label for="switchAnimbg"></label>
<span style="font-size: 16px;vertical-align: sub;">动画版</span>
</label>
<br />
<label class="user-select-none">
<span style="font-size: 16px;vertical-align: sub;">是否启用</span>
<input id="switch" class="Dswitch" type="checkbox" />
<label for="switch"></label>
<span style="font-size: 16px;vertical-align: sub;">非动画版</span>
</label>
</body>
</html>