: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; } —— 大部分浏览器下无视觉效果。
以下是最小可行结构,兼容 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 内的后续兄弟节点: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 不会自动清除——这会导致视觉与真实状态不一致。