:indeterminate伪类仅匹配js显式设置indeterminate=true的原生checkbox,需先appearance:none清除默认样式,再用::before重绘半选图形,并同步aria-checked="mixed"语义。

:indeterminate 伪类本身不“触发”半选,只匹配 JS 显式设置 indeterminate = true 的原生 <input type="checkbox">;不加 appearance: none 就写样式,基本等于白写。
为什么 :indeterminate 样式总没反应
不是选择器错了,而是你在跟浏览器原生控件硬刚:原生复选框的半选图形(横杠或填充块)由操作系统或 UA 样式私有渲染,background-color、border、color 这些对它完全无效。
- 写了
input:indeterminate { background: red; }却没加appearance: none→ 这行 CSS 没作用在可见区域上 - 用了 Element Plus 或 Ant Design 等框架 → 它们的
.el-checkbox input选择器优先级更高,直接覆盖你的input:indeterminate - 误以为 HTML 写
<input indeterminate>就能生效 → 浏览器忽略该 attribute,:indeterminate不匹配
必须走通的四步最小链
缺一不可,否则视觉和语义都不可控:
- 用 JS 设置状态:
checkboxElement.indeterminate = true(注意是 property 赋值,不是setAttribute) - CSS 清除默认外观:
input[type="checkbox"] { appearance: none; -webkit-appearance: none; } - 用伪元素重绘半选图形:
input:indeterminate::before { content: ""; display: block; width: 8px; height: 2px; background: #333; margin: 7px auto 0; } - 同步无障碍语义:
checkboxElement.setAttribute('aria-checked', 'mixed'),否则屏幕阅读器读不出“半选”
:indeterminate 和 :checked 的关系与陷阱
两者正交独立,但不能共存于同一套视觉逻辑中:
-
checkbox.indeterminate = true时,checkbox.checked仍可为true或false,互不影响 - 用户点击后,
indeterminate自动变为false,checked按常规翻转 —— 你得立刻判断是否要重置父节点状态 - 别写
input:checked:indeterminate,语法非法;CSS 中只能分别定义input:checked::before和input:indeterminate::before - 树形结构中,“部分子项选中 → 父项半选”必须手动计算:遍历子项,若
someChecked && !allChecked,才设parent.indeterminate = true
最易被忽略的是:设了 appearance: none 后,accent-color 对 :indeterminate 完全失效;Firefox 对 ::before 在 checkbox 上的居中支持不稳定,有时需加 position: relative 或微调 margin 值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











