0%

css-checkbox-customize-style

如何给 Checkbox 添加自定义样式?

各位老铁大家好,又是一个风和日丽的日子,人生苦短,不能总是留恋美好的风景,亦要时时刻刻学习,所谓活到老学到老。今天我们一起来学习一下如何给 html 中的 ckeckbox 添加自定义样式。

如何在 html 中实现 checkbox?

其实,html 中根本没有checkbox这种控件,也就是说,你不能这样写:

1
<checkbox>remember me</checkbox>

而是要像下面这样通过input来实现checkbox

1
2
<label for="remember-me">Remember me</label>
<input id="remember-me" type="checkbox" />

与之类似的控件还有radio,也需要用input来实现,如果大家对 input 控件感兴趣,可以看看这篇,可以这样说,掌握了input,基本上就掌握了 html 中form的半壁江山!

如何给 checkbox 添加样式?

给定如下 html,如果实现自定义 checkbox 的样式?包括颜色和选择框的形状。为了方便操作,我们在checkbox外层包裹了一层div

1
2
3
4
5
6
<body>
<div class="checkbox-container">
<input id="remember-me" type="checkbox" />
<label class="checkbox-label" for="remember-me">Remember me</label>
</div>
</body>

有的同学可能认为,这不是很简单的事吗?想要啥样式,直接写不就行了吗?呵呵,你可以试试,你会发现事情并不像你想象的那么简单,好了,长话短说,checkbox 的自定义样式主要分两个方面。

自定义选择框的颜色

默认情况下,checkbox 的选择框被选中时,应该显示蓝色背景+白色对勾,如果想更改这个颜色,那么可以直接使用 CSS 中的accent-color,这里accent不是口音的意思,而是强调的意思,accent-color也就是强调色。

假如要使上面的 checkbox 复选框被选中时变为紫色,那么可以按照如下方式书写 CSS。

1
2
3
input[id="remember-me"] {
accent-color: purple;
}

自定义选择框的形状

如果我想把 checkbox 选中时的对勾变成小方块该怎么办呢?改变checkbox外形可比改变它的颜色复杂多了,这时候你会发现无论你怎么写样式,都不生效。这是因为默认的样式是无法覆盖的,所以只能换策略,采用先禁用默认样式,然后添加自定义样式的方法。

禁用默认样式

禁用默认样式的方式有很多,比如隐藏 input 元素:

1
2
3
4
input[id="remember-me"] {
position: absolute;
z-index: -1;
}

但是,最推荐的还是下面这种。

1
2
3
input[id="remember-me"] {
appearance: none;
}

自定义 checkbox 样式

总体的思路就是使用before伪元素来绘制 checkbox 选择框,然后添加各种状态下的样式,比如鼠标悬停时、选中时、禁用时的样式等等。

完整代码如下,关键点都写到注释里面了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
/* Hide default input*/
input[id="remember-me"] {
appearance: none;
}

/* Draw a customer checkbox before label */
input[id="remember-me"] + label::before {
content: "";
display: inline-block;
width: 20px;
height: 20px;
border: 1px solid purple;
background-color: #fff;
border-radius: 4px;
margin-right: 16px;
/* Center the checkmark */
text-align: center;
line-height: 20px;
}

/* Change background color on hover */
input[id="remember-me"]:hover + label::before {
background-color: #dd94dd;
}

/* Add check mark when checked */
input[id="remember-me"]:checked + label::before {
content: "\2713";
color: white;
background-color: purple;
}

/* vertical center checkbox and label */
.checkbox-label {
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
}
</style>
</head>
<body>
<div class="checkbox-container">
<input id="remember-me" type="checkbox" />
<label class="checkbox-label" for="remember-me">Remember me</label>
</div>
</body>
</html>

伪元素的居中对齐

可以对伪元素的宿主元素采用 flex 布局,比如上面例子中的label标签,这样伪元素和字符串Remember-me就可以作为 flex 布局中的子元素进行对齐了。

上面的例子采用的是for/id形式的 label,如果是包裹式 label,情况则又不同了。

包裹式 label

如果采用的是包裹式 label,那么自定义的方式又有所不同,包裹式 label 如下所示,用一个 label 标签包裹住 input 控件。

1
2
3
4
5
6
<div class="checkbox-container">
<label class="checkbox-label">
Remember me
<input type="checkbox" />
</label>
</div>

这种方式下,当隐藏掉 label 包裹的 input 时,label 内部就空了,这导致添加伪元素十分不便,所以我们在 input 后面添加一个 span 元素,这个元素的作用无他,不过是为了方便添加伪元素。另外 label 已经是最外层元素了,所以 label 外层的 div 也就没有存在的必要了,将其删除,修改后的代码如下:

1
2
3
4
5
<label class="checkbox-container">
<input id="remember-me" type="checkbox" />
Remember me
<span class="checkmark"></span>
</label>

样式文件如下,思路都在注释里面了,直接看吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<style>
.checkbox-container {
position: relative; /*子元素有absolute布局,这里要做relative*/
padding-left: 36px; /* 为label标签和选择框之间留出空间 */
cursor: pointer; /* 鼠标悬停时变成小手 */
user-select: none; /* 防止选择时选中label文本(Remember me) */
}
/* 隐藏默认的选择框 */
input[type="checkbox"] {
appearance: none;
}
/* 利用span元素创建一个选择框 */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 24px;
width: 24px;
background-color: #eee;
}
/* 鼠标悬停时改变选择框背景色为深灰色,注意这里的选择器很复杂,为的就是无论悬停在文本上还是选择框上,背景都改变如果只是简单的使用.checkmark,那么鼠标悬停在文本上时,背景色不会改变。*/
.checkbox-container:hover input ~ .checkmark {
background-color: #ccc;
}
/* 选中时,改变选择框背景色为蓝色 */
.checkbox-container input:checked ~ .checkmark {
background-color: #2196f3;
}
/* 绘制选择框内的对勾,这里实际上利用border绘制了一个横折,然后旋转45形成对勾 未选中时,默认隐藏对勾*/
.checkmark:after {
content: "";
position: absolute;
display: none;
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
}
/*选中时显示对勾 */
.checkbox-container input:checked ~ .checkmark:after {
display: block;
}
</style>

今天就写到这里啦,大家有什么想法,欢迎留言讨论,我们下期再见。