在 CSS 中进行切换
我们来换个玩法!
入门
嗯,滑块
旋钮造型
等等,还有更多!
我们今天的工作就到此结束了!
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
我们来换个玩法!
最近我做了一个项目,想用 Materialize CSS,但用过之后发现,虽然它是个不错的库,但并不适合我的项目。不过,我很喜欢他们设计的 switch 元素,所以决定自己用 CSS 重写一遍。
这样做需要我涉猎之前从未接触过的 CSS 领域,即伪元素。通过操作 `<code>`::before和::after`<code>`,我可以将复选框变成一个功能性的开关。
下图是最终产品。它是一个可以从关闭切换到开启的开关,关闭时会变成灰色且无法使用。
入门
我们将从简单的复选框开始,并将其包裹在一个标签中,这样当用户点击标签时,就可以切换复选框的选中状态。
为了方便用户访问,您应该始终将标签与表单元素结合使用。
为了确保我们的 CSS 不会影响网站上的其他复选框,我们将给标签添加一个类,并随着我们的继续修改该类及其后代。
<label class="switch">
Off
<input type="checkbox">
On
</label>
让我们来设置 CSS:
.switch input[type="checkbox"] {
}
我们首先需要做的就是去掉默认的复选框样式。这花了我一些时间研究,但我找到了解决方案-webkit-appearance: none;。现在我们的复选框将消失。
接下来,我们需要确定旋钮(红色或蓝色圆圈)以及旋钮滑动的滑块(背景中的灰色矩形)的位置。这些元素将使用伪元素创建,并且需要相对于复选框元素的位置进行移动。
这是一个重要的提示,我们需要为旋钮设置绝对定位样式,但默认情况下,绝对定位会基于整个窗口。我们需要将其设置在复选框上,因为它是 `<div>`和`<span>` 伪元素position: relative的父元素。::before::after
最后,我们希望开关出现后,周围留出一些间距,这样“开”和“关”字就不会紧挨着它,我们可以使用边距来实现这一点。
.switch input[type="checkbox"] {
-webkit-appearance: none;
position: relative;
margin: 0 1rem;
}
这样就设置好了复选框。但现在我们什么都看不到,所以我们来创建滑块。
嗯,滑块
没有什么比一盘迷你汉堡更让我开心的了。但这是篇CSS文章,不是那种提供美式食物、播放乡村音乐、墙上贴满奇奇怪怪东西的小镇烧烤店。
在这种情况下,滑块就是旋钮移动的轨道。我们将用::after伪元素来创建它。
但首先,什么是::after伪元素?或者说::before,什么是伪元素?伪元素是指带有各种标签的元素,这些标签可以处理各种不同的操作。我知道这样的回答很笼统,可能没什么帮助,但伪元素确实有很多种。有些伪元素,比如 `<p>`,::first-line可以修改段落的第一行。还有一个实验性的伪元素,可以让你对文本进行一些修改::spell-check。MDN 上有很多关于伪元素的信息。
::before`<div>` 和 `<span>`::after是大多数 HTML 元素中都存在的元素,它们被视为其元素的子元素。`<div>`::before是第一个子元素,`<span>`::after是最后一个子元素。就我们的目的而言,哪个是第一个子元素或哪个是最后一个子元素并不重要。这些元素可以用于很多用途,甚至可以用来创建胡须。
但我们会尽量简化,用它::after来创建滑块。它就是一个普通的灰色矩形框。
要针对它,我们只需将其添加::after到新的 CSS 规则中即可。
.switch input[type="checkbox"]::after {
}
要让它显示出来,我们需要做五件事。首先,伪元素需要一些内容。我们的伪元素是一个简单的空字符串,所以content: ''就足够了。其次,它需要有一个显示属性。我们把它设为block,因为经过一些调整,我发现这样效果最好。它还需要一个背景颜色,我选择了grey。
不要犯我总是犯的错误,去设置
color属性!color这是文本!background这是我们想要设置的内容!
最后,我们需要设置高度和宽度。由于它应该设置在文本正文中,因此基于根元素的 em(rem)单位似乎是最合理的。我将其宽度设置为 1 rem,高度设置为 0.5 rem。
.switch input[type="checkbox"]::after {
content: '';
display: block;
width: 1rem;
height: 0.5rem;
background-color: grey;
}
一个灰色的矩形突然出现!
旋钮造型
现在来说说旋钮。这里有一个旋钮,它可以向左或向右,但始终是圆形,始终带有阴影(使其具有一些 3D 效果),并且始终具有相同的内容和大小,因此我们希望编写 CSS 时遵循 DRY 原则,即不要重复自己。
我们想为::before伪元素编写一个基线。
.switch input[type="checkbox"]::before {
}
同样,我们需要给它添加内容、尺寸和显示属性,才能让它显示出来。
.switch input[type="checkbox"]::before {
content: '';
display: block;
width: 1rem;
height: 1rem;
}
这样就能得到一个正方形。不过我们现在还看不到它,因为它还没有颜色,所以我们需要设定复选框选中和未选中时的规则,因为颜色会根据这个值而改变。
选中复选框很简单,我们可以创建一个新规则来选择它:checked。选中未选中的复选框就稍微复杂一些,因为没有直接的复选框:unchecked。我们需要使用:not()伪选择器,所以我们可以创建两条新规则:
.switch input[type="checkbox"]:checked::before {
}
.switch input[type="checkbox"]:not(:checked)::before {
}
这里的顺序很重要。我们想要定位的是::before已选中复选框类型的输入元素的伪元素,该伪元素是 switch 类元素的子元素。我们不希望:checked 定位到 `after`, ::before因为::before它没有 ` checkedattribute` 属性。
如果选中,我希望它显示为蓝色并向左移动 10 个像素。如果未选中,我希望它显示为红色并向右移动 10 个像素。
.switch input[type="checkbox"]:checked::before {
left: 10px;
background-color: blue;
}
.switch input[type="checkbox"]:not(:checked)::before {
right: 10px;
background-color: red;
}
因为我们要修改属性,left所以right我们的基线需要设置为position: absolute:
.switch input[type="checkbox"]::before {
content: '';
display: block;
position: absolute;
width: 1rem;
height: 1rem;
}
现在我们快完成了。旋钮在轨道上有点偏离中心,为了解决这个问题,我发现将顶部位置设置为 -0.25 就能把它调整到我想要的位置:
.switch input[type="checkbox"]::before {
content: '';
display: block;
position: absolute;
top: -0.25rem;
width: 1rem;
height: 1rem;
}
最后,我们把它变成一个带阴影的圆。圆很简单,只需设置 50% 的圆弧半径即可。至于阴影,我从来不手动绘制,我找到了一个很棒的在线工具。我喜欢用CSSMatic。它有一个实时阴影工具,可以自动生成代码。根据我设置的圆弧半径和数值,基线选择器的最终 CSS 代码如下:
.switch input[type="checkbox"]::before {
content: '';
display: block;
position: absolute;
top: -0.25rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
-webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
}
瞧,这就是一个功能齐全的开关!
等等,还有更多!
任何表单元素都离不开样式来定位。:disabled.我们的用户需要一个视觉提示来知道该元素当前无法使用。为此,我们可以选取我们的旋钮::before元素,并在复选框禁用时更改其颜色:
.switch input[type="checkbox"]:disabled::before {
background-color: darkgrey;
}
如果旋钮被禁用,它会变成灰色。尝试在input标签中添加“disabled”进行测试。
我们今天的工作就到此结束了!
以下是完整代码:
<label class="switch">
Off
<input type="checkbox">
On
</label>
.switch input[type="checkbox"]:checked::before {
left: 10px;
background-color: blue;
}
.switch input[type="checkbox"]:not(:checked)::before {
right: 10px;
background-color: red;
}
.switch input[type="checkbox"]::before {
content: '';
display: block;
position: absolute;
top: -0.25rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
-webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75);
}
.switch input[type="checkbox"]::after {
content: '';
display: block;
width: 1rem;
height: 0.5rem;
background-color: grey;
}
.switch input[type="checkbox"] {
-webkit-appearance: none;
position: relative;
margin: 0 1rem;
}
.switch input[type="checkbox"]:disabled::before {
background-color: darkgrey;
}
这是一个简单的小开关,可以为网站增添一些特色。它非常适合用于二元选择场景,例如用户想要这个选项或想要那个选项。
您可以随意使用和修改。尝试调整大小或颜色,让它更美观,尽情发挥创意。如果您发现任何可以用 CSS 实现的更佳方法,请告诉我。
祝您编程愉快!
文章来源:https://dev.to/jckuhl/making-a-switch-in-css-5no
