:checked伪类本身不触发重绘,但配合+或~选择器可控制后续兄弟元素样式,实现无JS单选/多选视觉反馈;因label非input子元素,:checked>label无效。

:checked 本身不触发重绘,但配合 +(相邻兄弟)或 ~(通用兄弟)选择器时,能精准控制后续兄弟元素的样式——这是实现无 JS 单选/多选视觉反馈的核心机制。
为什么 :checked + label 能生效,而 :checked > label 不行
:checked 是伪类,只作用于 <input type="checkbox"> 或 <input type="radio"> 元素自身。它不能“向上”选父级,也不能“向下”选子级,因为 label 通常不是它的子元素,而是平级或后续兄弟。
-
:checked + label:要求label紧跟在input后面(顺序、同层),例如<input><label>... -
:checked ~ label:允许中间有其他同层元素,只要label在input之后即可 -
:checked > label:永远无效——label几乎不会是input的子元素(HTML 规范禁止)
单选按钮(radio)切换背景色的典型写法
关键在于用 name 统一分组,并确保 label 与 input 同层且顺序正确:
<input type="radio" name="theme" id="light"> <label for="light">浅色模式</label> <p><input type="radio" name="theme" id="dark"> <label for="dark">深色模式</label>
CSS 中这样写:
立即学习“前端免费学习笔记(深入)”;
input[type="radio"] {
display: none; /* 隐藏原生控件 */
}
input[type="radio"]:checked + label {
background: #007bff;
color: white;
padding: 4px 12px;
border-radius: 4px;
}- 必须用
for属性关联label和input,否则点击文字无法触发选中 - 若用
<label><input>文字</label>嵌套结构,则应改用input:checked ~ label或直接写label input:checked + span等更具体路径 -
display: none是安全的;用visibility: hidden或opacity: 0可能导致点击失效(尤其 Safari)
多选(checkbox)加图标状态反馈的常见坑
想让选中时显示 ✔️ 图标?别直接在 label 里硬写 HTML,用伪元素更可控:
input[type="checkbox"] {
display: none;
}
input[type="checkbox"] + label::before {
content: "⬜";
margin-right: 8px;
}
input[type="checkbox"]:checked + label::before {
content: "✔️";
}- ⚠️
::before必须作用于label,不能写成input:checked::before(:checked不支持伪元素) - 某些字体下 ✔️ 渲染模糊,可改用 SVG 或 Unicode ✅(U+2705),或用
background-image加透明 PNG - 移动端点击热区小:给
label加padding或min-height,别只依赖文字大小
真正难的是处理「部分选中」状态(如树形多选)、禁用态联动、或和表单验证结合——这些已超出纯 CSS 能力边界,得靠 JS 补位。但仅做视觉开关,:checked 配合兄弟选择器足够稳、够快、够轻量。










