复选框和开关的样式
我可能不是唯一一个对浏览器默认设置感到沮丧的开发人员<input type="checkbox">
。
首先:它不可扩展。在这个例子中,字体大小已经放大到200%
,但复选框仍然保持其根元素的大小,即13.333333px
:
在本教程中,我们将剖析浏览器的默认复选框,看看是否可以做得更好。
首先,我们需要清除默认样式appearance:none
并设置初始大小 - 这是一个相对单位em
:
[type=checkbox] {
appearance: none;
aspect-ratio: 1;
box-sizing: border-box;
font-size: 1em;
width: 1em;
}
它background-color
应该适应暗黑模式,所以我们会检查它是否与任何系统颜色匹配。它似乎与Field
系统颜色匹配,所以我们就使用它。
对于边框颜色 — 在 Chrome 中 — 它与系统颜色相匹配ButtonBorder
,但由于 Safari 使用更浅的颜色 ButtonBorder
,因此我们将使用GrayCanvas
在两种浏览器中都适用的颜色。
我们将添加一些 CSS 自定义属性,稍后我们将使用这些属性来创建变体。
对于border-radius
和margin
,我们将使用默认值,但将它们转换为相对单位em
。
似乎border-width
可以使用以下公式来缩放:
(4/3) / root size
由于根的大小为13.333333px
,我们现在有:
[type=checkbox] {
--_bdw: calc(1em * (4/3) / 13.333333);
appearance: none;
aspect-ratio: 1;
background: var(--_bg, Field);
border: var(--_bdw) solid var(--_bdc, GrayText);
border-radius: var(--_bdrs, .2em);
box-sizing: border-box;
font-size: 1em;
margin: var(--_m, .1875em .1875em .1875em .25em);
position: relative;
width: 1em;
}
让我们看看它是否可扩展:
太棒了!黑暗模式怎么样?
这就是我喜欢系统颜色的原因!接下来,让我们添加浏览器在未选中复选框时使用的悬停效果。
我们将混合CanvasText
,在亮模式下为黑色,在暗模式下为白色,并简单地更新--_bdc
我们在上一步中添加的属性:
@media (hover: hover) {
&:not(:checked):hover {
--_bdc: color-mix(in srgb, GrayText 60%, CanvasText 40%);
}
}
勾号
现在来看看复选标记。我们可以在 -element 元素中添加一个旋转的 CSS 框来实现::after
:
[type=checkbox]::after {
border-color: GrayText;
border-style: solid;
border-width: 0 0.15em 0.15em 0;
box-sizing: border-box;
content: '';
aspect-ratio: 1 / 1.8;
rotate: 40deg;
width: 0.375em;
}
虽然这样也行,但我更喜欢在蒙版中使用 SVG,因为它更灵活。为此,我们将为蒙版添加一个属性,并--_bga
为 元素的背景添加另一个属性::after
,该属性将设置为复选标记的颜色。
[role=checkbox] {
--_bga: Field;
--_mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="3" stroke="%23000" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path d="M5 12l5 5l10 -10"/></svg>');
&::after {
background: var(--_bga, transparent);
content: "";
inset: 0;
position: absolute;
mask: var(--_mask) no-repeat center / contain;
-webkit-mask: var(--_mask) no-repeat center / contain;
}
}
所以,我们现在确实有一个复选标记,只是我们看不到它,因为 mask-color 设置为transparent
。
让我们使用 -state 更新复选框被点击时的颜色:checked
。但在此之前,我们需要确定具体的颜色!
Safari 是唯一支持系统颜色的浏览器AccentColor
,因此我们需要为其创建自己的变量,--_accent
在 Mac 上它对应于#0075ff
:
[type=checkbox] {
--_accent: #0075ff;
&:checked {
--_bdc: transparent;
--_bg: var(--_accent);
--_bga: Field;
}
}
让我们看看我们构建了什么:
那么黑暗模式呢?我们需要--_accent
先更新 -property 属性,因为AccentColor
它目前还不支持所有浏览器:
@media (prefers-color-scheme: dark) {
--_accent: #99C8FF;
}
让我们检查一下:
太棒了!现在我们要添加的就是:checked:hover
-state 了,它和我们之前添加的 border-hover 类似:
@media (hover: hover) {
&:checked:hover {
--_bg: color-mix(in srgb, var(--_accent) 60%, CanvasText 40%);
}
}
让我们比较一下它在 Chrome、Safari 和 Firefox 中的外观:
看来我们通过了考验!
变体
创建变体非常简单:只需更新几个属性即可。例如:
.rounded { --_bdrs: 50%; }
.square { --_bdrs: 0; }
然后在 HTML 中:
<input type="checkbox" class="rounded">
<input type="checkbox" class="square">
— 或者全力以赴并创建老式的复选框:
关于圆形复选框的一点说明:这是一种不好的做法,正如您在这篇精彩的文章中所读到的。不过也有一些例外,比如这个“图片选择器”:
开关
对于开关,我们将添加一个role="switch"
,因此它是:
<input type="checkbox" role="switch">
Apple 最近添加了自己的 switch-control,但role="switch"
它是跨浏览器的。同样,我们只需要更新之前创建的许多属性:
[role=switch] {
--_bdc--hover: transparent;
--_bdrs: 1em;
--_bg: #d1d1d1;
--_bga: Field;
--_mask: none;
aspect-ratio: 1.8 / 1;
border: 0;
display: grid;
padding: .125em;
place-content: center start;
width: 1.8em;
&::after {
border-radius: 50%;
height: .75em;
inset: unset;
position: static;
width: .75em;
}
&:checked {
--_bg: var(--_bg--checked, var(--_accent));
justify-content: end;
}
}
这给了我们:
演示
就是这样!下面是带有演示的 Codepen:
黑客和缝线
以下是我在 Codepen 上使用复选框完成的一些内容的集合:
Checkbox 影院
选择你的座位。还可以修改为选择火车、飞机上的座位……
Skyline 复选框
点击窗户打开公寓里的灯……
数字填色
首先选择一种颜色(使用<input type="radio">
),然后单击相应的数字(复选框)...
点对点
不需要 JavaScript,但我把它留在那里供您玩……
来自地狱的条款和条件
检查全部内容...
每日切换
Alvaro Montoro 正在创建一个巨大的开关/拨动开关系列——2024 年每天一个。点击此处查看。
封面照片由Tara Winstead拍摄
文章来源:https://dev.to/madsstoumann/styling-checkboxes-and-switches-pf0