:checked 选择器仅对 checkbox、radio 和多选 select 中的 option 生效,需配合隐藏原生控件+伪元素实现视觉反馈,不响应纯 JS 属性修改,且表单重置时状态同步但 class 不自动更新。

如何用 :checked 选择器精准捕获勾选状态
:checked 只对 、 和 (在 中)生效。它不作用于 type="text" 或自定义组件,也不响应 JavaScript 手动设置的 checked 属性变更(除非 DOM 状态同步更新)。
关键点:浏览器只在用户交互或显式调用 element.click() / element.checked = true 并触发重绘后才更新 :checked 的匹配状态。
常见写法与易错路径
不能直接给 input 加样式(因原生控件不可见且跨浏览器渲染差异大),必须借助相邻/子元素联动:
- 用
+ label选中紧邻的label(要求input在label前) - 用
~ label选中后续任意位置的label(需同级) - 用
input:checked + .custom-control控制自定义视觉层
错误示例:input:checked { background: red; } —— 大部分浏览器下无视觉效果。
立即学习“前端免费学习笔记(深入)”;
实际可运行的 CSS 控制逻辑
以下是最小可行结构,兼容 Chrome/Firefox/Safari:
input[type="checkbox"] {
position: absolute;
opacity: 0;
pointer-events: none;
}
input[type="checkbox"] + label::before {
content: "☐";
margin-right: 8px;
}
input[type="checkbox"]:checked + label::before {
content: "☑";
}
说明:
-
opacity: 0隐藏原生框但保留可点击区域;pointer-events: none防止遮挡下方内容 - 必须用
::before伪元素承载图标,否则无法通过:checked触发切换 - 若
label包裹input,可用label input:checked ~ .icon,但需确保.icon是label内的后续兄弟节点
radio 组与多选场景下的注意事项
:checked 在 radio 组中天然互斥,但 CSS 无法感知“当前未被选中的其他选项”——也就是说,你不能用纯 CSS 写出“除当前选中外,其余 radio 全部变灰”这种逻辑。
能做的只有单向控制:
input[value="a"]:checked ~ .section-a { display: block; }input[type="radio"]:checked + label { color: #1890ff; }
如果需要反向样式(如禁用未选中的 radio 对应的描述文字),必须配合 JS 设置 class 或改用 + :has()(注意::has() 在 Safari 15.4+ 和 Chrome 105+ 支持,旧版不兼容)。
真正容易被忽略的是:当表单通过 form.reset() 重置时,:checked 状态会立即同步,但依赖 JS 维护的 class 不会自动清除——这会导致视觉与真实状态不一致。










