:checked不区分单选框和复选框,需用[type="radio"]:checked和[type="checkbox"]:checked显式限定;它仅作用于同级后续兄弟元素,且隐藏原生控件须用绝对定位或clip避免破坏可访问性。

用 :checked 区分单选框和复选框的选中状态
:checked 本身不区分 type,它只匹配当前被用户选中的 或 。真正区分它们的是选择器写法——必须显式带上 type 属性限定。
常见错误是直接写 :checked { ... },这样会同时命中 radio 和 checkbox,导致样式冲突。正确做法是:
-
input[type="radio"]:checked—— 只作用于选中的单选框 -
input[type="checkbox"]:checked—— 只作用于选中的复选框 - 若还需进一步限定(比如某组 radio),可加
name属性:input[type="radio"][name="theme"]:checked
为什么不能只靠 input:checked?
因为 input:checked 是宽泛匹配,浏览器会把所有已选中的 都算进去,不管它是 radio 还是 checkbox,甚至包括 type="option"(虽不合法但解析时可能误匹配)。这在需要差异化视觉反馈时非常危险——比如你想给复选框加 ✓ 图标、给单选框加实心圆点,用通用选择器会导致图标错位或重复渲染。
更隐蔽的问题是:当页面同时存在两类控件,且你为 input:checked 设置了 background 或 transform,它们会共用同一套动画或过渡效果,而 radio 和 checkbox 的交互节奏本就不同(单选是互斥切换,复选是独立开关)。
:checked 在真实 DOM 结构中的生效边界
:checked 只能影响**同级后续兄弟元素**,不能向上选父容器,也不能跨层级。这意味着你必须控制 HTML 结构顺序:
- ✅ 推荐结构:
→ 可用input[type="checkbox"]:checked + label::before - ❌ 错误结构:
→input在label后面,但不是其兄弟,无法用+或~关联 - ⚠️ 嵌套结构:
→ 可用input:checked + *::before,但仅限紧邻的下一个兄弟;若中间插了就断链
容易被忽略的兼容性与可访问性细节
Safari 对 input[type="radio"]:checked ~ label::after 的伪元素更新有轻微延迟,尤其配合 transition 时。这不是 bug,而是渲染管线对表单状态变更的响应策略不同——建议避免对 ::before/::after 做颜色+尺寸+位置三重过渡。
真正的硬约束在于可访问性:display: none 会彻底移除 input 的焦点能力,屏幕阅读器无法播报状态变更。必须用 position: absolute; left: -9999px 或 clip: rect(1px, 1px, 1px, 1px) 隐藏原生控件,同时保留其语义和键盘可操作性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











