使用到的知识点:
- 在css中定义全局变量
- calc函数
- 伪类选择器结合input的各种状态控制
- @media适配dark模式
定义css中用到的变量
在 :root{} 中,通过 --a-b的形式定义整个按钮中用到的一些布局和颜色值的变量
:root{
/* 按钮宽度 */
--button-width: 500px;
/* 按钮高度 */
--button-height: 295px;
/* 里面圆形直径 */
--toggle-diameter: 255px;
/* 按钮与里面圆形之间的间距 */
--button-toggle-offset: calc((var(--button-height) - var(--toggle-diameter)) / 2);
/* 里面圆形阴影的大小 */
--toggle-shadow-offset: 10px;
/* 里面圆形在长按状态下的宽度 */
--toggle-wider: 333px;
/* 浅灰色 */
--color-grey: #e9e9e9;
/* 深灰色 */
--color-dark-grey: #39393D;
/* 绿色 */
--color-green: #30d158;
}
html部分
<label for="toggle">
<input type="checkbox" id="toggle">
<span></span>
</label>
直接用css去调整span的形态来构建按钮,跟checkbox一起放在一个label里,通过checkbox的状态改变来触发span的改变。
css部分
原始的样子
span{
display: inline-block;
width: var(--button-width);
height: var(--button-height);
background-color: var(--color-grey);
border-radius: calc(var(--button-height) / 2);
position: relative;
}
span::after{
content: '';
display: inline-block;
width: var(--toggle-diameter);
height: var(--toggle-diameter);
background-color: white;
border-radius: calc(var(--toggle-diameter) / 2);
position: absolute;
top: var(--button-toggle-offset);
transform: translateX(var(--button-toggle-offset));
box-shadow: var(--toggle-shadow-offset) 0 calc(var(--toggle-shadow-offset) * 4) rgba(0, 0, 0, 0.1);
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh ;
}
按钮里面的圆形,直接使用span::after伪类来描述,此刻你会得到一个居中显示的没有啥交互的switch按钮
点击交互,让小圆形动起来,背景色改变,长按时小圆形变长等
input:checked + span{
background-color: var(--color-green);
}
如果页面比较复杂,为了区分不同的input类型,应该用input[type='checkbox']来定位元素,这里因为只有一个input标签,就简单处理了。通过:check + span 获取到选中之后的按钮,背景变为绿色。
input:checked + span::after{
transform: translateX(calc(var(--button-width) - var(--toggle-diameter) - var(--toggle-shadow-offset)));
box-shadow: calc(var(--toggle-shadow-offset) * -1) 0 calc(var(--toggle-shadow-offset) * 4) rgba(0, 0, 0, 0.1);
}
选中之后处理里面的小圆形,translateX改变位置,box-shadow也把阴影的方向做了改变。
input:active + span::after{
width: var(--toggle-wider);
}
:active获取长按状态,改变小圆形的宽度。
input:active:checked + span::after{
transform: translateX(calc(var(--button-width) - var(--toggle-wider) - var(--button-toggle-offset)));
}
:active:checked 获取到选中且在长按下的状态,这个时候需要调整下小圆形的left,达到未选中时长按小圆形往右边变长,选中时长按小圆形往左边变长的效果。
走到这一步基本上iOS风格的switch交互就实现了,可以把input的display设为none来隐藏掉,span和span::after里面都加上
transition: all 0.3s ease-in-out;
来实现平滑的动画效果。
适配dark模式
@media(prefers-color-scheme: dark){
body{
background-color: #1c1c1e;
}
span{
background-color: var(--color-dark-grey);
}
}
@media(prefers-color-scheme: dark)
里面的css效果,会在系统设置成dark模式在被启用,整个效果如下图
本文是一篇记录笔记,视频源:CodingStartUp