点此查看 所有教程、项目、源码导航
文章目录
- [1. 开篇介绍与环境引入](#1. 开篇介绍与环境引入)
-
- [1.1 本章节学习背景](#1.1 本章节学习背景)
- [1.2 引入 Bootstrap 5](#1.2 引入 Bootstrap 5)
- [2. 复选框使用方法](#2. 复选框使用方法)
-
- [2.1 基础复选框](#2.1 基础复选框)
- [2.2 默认勾选](#2.2 默认勾选)
- [2.3 禁用复选框](#2.3 禁用复选框)
- [2.4 一行横向排列](#2.4 一行横向排列)
- [3. 底层实现关键点解析](#3. 底层实现关键点解析)
-
- [3.1 form-check 容器](#3.1 form-check 容器)
- [3.2 隐藏原生输入框](#3.2 隐藏原生输入框)
- [3.3 绘制方框](#3.3 绘制方框)
- [3.4 选中之后绘制对勾](#3.4 选中之后绘制对勾)
- [3.5 禁用样式](#3.5 禁用样式)
- [3.6 横向排列](#3.6 横向排列)
- [4. 小结](#4. 小结)
1. 开篇介绍与环境引入
1.1 本章节学习背景
上一节我们学习了 form-select 下拉选择框,理解了 appearance: none 清除原生控件样式、自定义下拉箭头的思路。这一节我们学习 Bootstrap 5 的复选框。
浏览器原生复选框样式很难统一,大小、勾选标记、颜色在不同浏览器里面差别明显,而且不容易自定义美化。
Bootstrap 单独封装了一套自定义复选框,不再直接美化原生 input,而是把原生输入框隐藏,利用 label 和伪元素绘制勾选方框与对勾,实现跨浏览器一致的外观。
按照本系列固定的学习思路,我们不会仅仅记住类名、复制代码。先学会复选框的使用方式,之后通过精简的 CSS 复刻,看懂它背后依靠哪些 CSS 特性实现,反过来巩固我们的 CSS 基础,完善前端技术体系。
复选框属于 CSS + 少量交互的组件,不需要手写 JavaScript。
1.2 引入 Bootstrap 5
这里着重强调:引入 Bootstrap,本质就是引用别人提前写好的 CSS 类库以及配套的 JS,不需要把完整源码复制到页面当中,通过外链加载即可。想要使用自定义复选框,只需要引入 Bootstrap 的 CSS 文件。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title></title>
<!-- Bootstrap 5 CSS -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.8/css/bootstrap.min.css">
</head>
<body>
<!-- Bootstrap JS + Popper,用于部分交互 -->
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.8/js/bootstrap.bundle.min.js"></script>
</body>
</html>
2. 复选框使用方法
首先我们看下原生复选框的模板,代码:
html
<input type="checkbox" value="">同意
效果:

接下来我们看下BootStrap5的。
2.1 基础复选框
外层使用 form-check,form-check-input 放到 input,form-check-label 放到标签,input 和 label 通过 id、for 绑定,点击文字同样可以选中。
html
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="check1">
<label class="form-check-label" for="check1">
同意用户协议
</label>
</div>
效果:

2.2 默认勾选
给 input 添加 checked 属性,页面加载默认处于选中状态。
html
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="check2" checked>
<label class="form-check-label" for="check2">
默认勾选选项
</label>
</div>
效果:

2.3 禁用复选框
添加 disabled,复选框无法点击;同时给 label 加上 disabled 类,文字同步变灰,提示不可操作。
html
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="check3" disabled>
<label class="form-check-label" for="check3">
禁用选项
</label>
</div>
效果:

2.4 一行横向排列
多个复选框想要放在同一行,在外层使用 form-check-inline。
html
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inline1">
<label class="form-check-label" for="inline1">篮球</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inline2">
<label class="form-check-label" for="inline2">阅读</label>
</div>

3. 底层实现关键点解析
下面是精简复刻版本,去掉大量浏览器兼容代码,只保留核心逻辑。
使用上面的 HTML 代码,加下面自己写的 CSS,能得到基本类似的效果,大家可以尝试下。
3.1 form-check 容器
css
.form-check {
position: relative;
display: block;
/* 左侧留出空间,用来放置自定义方框 */
padding-left: 1.5em;
margin-bottom: 0.125rem;
}
效果:

3.2 隐藏原生输入框
css
.form-check-input {
position: absolute;
left: 0;
top: 0.25em;
/* 层级压低,放到伪元素下层 */
z-index: -1;
/* 透明度隐藏,不是 display:none,保留表单、焦点、键盘访问能力 */
opacity: 0;
}
效果:

3.3 绘制方框
css
.form-check-input ~ .form-check-label {
cursor: pointer;
}
/* before 伪元素:绘制空白方框 */
.form-check-input ~ .form-check-label::before {
content: "";
position: absolute;
top: 0.25em;
left: 0;
width: 1em;
height: 1em;
/* 和整套表单统一边框色 */
border: 1px solid #dee2e6;
border-radius: 0.25em;
background-color: #fff;
}
效果:

3.4 选中之后绘制对勾
css
/* after 伪元素:对勾,使用边框旋转方案 */
.form-check-input:checked ~ .form-check-label::after {
content: "";
position: absolute;
top: 0.45em;
left: 0.25em;
width: 0.5em;
height: 0.75em;
border: solid #fff;
/* 只保留右下两条边框,旋转之后形成对勾 */
border-width: 0 0.15em 0.15em 0;
transform: rotate(45deg);
}
/* 选中时,方框背景和边框切换为主色 */
.form-check-input:checked ~ .form-check-label::before {
background-color: #0d6efd;
border-color: #0d6efd;
}
效果:

3.5 禁用样式
css
.form-check-input:disabled ~ .form-check-label {
color: #6c757d;
cursor: default;
}
/* 禁用状态下方框背景改为浅灰 */
.form-check-input:disabled ~ .form-check-label::before {
background-color: #e9ecef;
}
效果:

3.6 横向排列
css
/* 行内块,多个选项并排 */
.form-check-inline {
display: inline-block;
margin-right: 1rem;
}
效果:

4. 小结
自定义复选框最核心的思路就是:原生 input 只负责保存选中状态,视觉全部交给 label 的伪元素绘制。
- 原生输入框设置
opacity:0隐藏,但是仍然保留可聚焦、可选中的原生能力,不会破坏表单提交、键盘访问; - 通过相邻兄弟选择器
~,监听 input 的:checked、:disabled状态,切换伪元素外观; - 边框颜色继续使用
#dee2e6,和前面输入框、下拉框保持统一;选中填充色使用主题蓝色; form-check-inline依靠行内块实现同行排布;- 如果需要半选(indeterminate)状态,Bootstrap 也做了支持,一般用于全选框;
- 和普通 input 不一样,这套自定义控件强烈要求 input 和 label 紧邻,否则兄弟选择器无法生效。