首页 > 编程笔记 > CSS笔记

CSS :indeterminate用法详解

复选框元素除了选中和没选中的状态,还有半选状态,半选状态多用在包含全选功能的列表中。

没有原生的 HTML 属性可以设置半选状态,半选状态只能通过 JavaScript 进行设置,这一点和全选不一样(全选有 checked 属性)。
// 设置checkbox元素为半选状态
checkbox.indeterminate = true;
:indeterminate 伪类顾名思义就是“不确定伪类”,由于平常只在复选框中应用,因此很多人会误认为 :indeterminate 伪类只可以匹配复选框,但实际上它还可以匹配单选框和进度条元素 <progress>。

下面我们一起看一下 :indeterminate 伪类在这 3 类元素中的表现。

:indeterminate伪类与复选框

不同浏览器下复选框的半选状态的样式是不一样的,Chrome 浏览器下是短横线,Firefox 浏览器下是蓝色渐变大方块,IE 浏览器下则是黑色小方块。

由于使用 Chrome 浏览器的用户占比最大,因此如果大家想要借助原生复选框元素自定义复选框的半选状态,我个人推荐使用 Chrome 浏览器的短横线样式。

短横线的形状就是一个矩形小方块,它的实现很简单,CSS 示意代码如下:
:indeterminate + .cs-checkbox::before {
   content: "";
   display: block;
   width: 8px;
   border-bottom: 2px solid;
   margin: 7px auto 0;
}
最终模拟的复选框半选状态的对比效果如下图所示。


图 1 Chrome浏览器下复选框原生半选和自定义半选的效果对比

复选框元素的半选伪类 :indeterminate 从 IE9 浏览器就开始支持了,因此可以放心使用。

:indeterminate伪类与单选框

对于单选框元素,当所有 name 属性值一样的单选框都没有被选中的时候 :indeterminate 伪类会匹配;如果单选框元素没有设置 name 属性值,则其自身没有被选中的时候 :indeterminate 伪类也会匹配。

例如:
:indeterminate + label {
   background: skyblue;
}
<input type="radio" name="radio"><label>文案1</label>
<input type="radio" name="radio"><label>文案2</label>
<input type="radio" name="radio"><label>文案3</label>
<input type="radio" name="radio"><label>文案4</label>
此时总共有 4 个 name 属性值为 "radio" 的单选框,默认其中没有一个被选中,此时 :indeterminate 伪类匹配这 4 个单选框,<label> 元素的背景色表现为天蓝色,如下图所示。


图 2 :indeterminate伪类匹配全部单选框

接下来,只要其中任意一个单选框被选中,所有单选框都会失去 :indeterminate 伪类的匹配,文案的背景色消失,如下图所示。


图 3 所有单选框失去 :indeterminate 伪类的匹配

这个伪类可以用来提示用户尚未选择任何单选项,如果用户选中了某个单选项,则提示自动消失,示意代码如下:
:indeterminate ~ .cs-valid-tips::before {
   content: "您尚未选择任何选项";
   color: red;
   font-size: 87.5%;
}
为排除干扰,方便学习,这里只展现核心 HTML:
<input type="radio" id="radio1" name="radio">
<label for="radio1">单选项1</label>
<input type="radio" id="radio2" name="radio">
<label for="radio2">单选项2</label>
<input type="radio" id="radio3" name="radio">
<label for="radio3">单选项3</label>
<-- 这里显示提示信息 -->
<p class="cs-valid-tips"></p>
用户尚未选中任何选项时的样式如下图所示。


图 4  未选中任何选项时出现提示文案

选中选项后,红色的提示文案消失,如下图所示。


图 5 选中选项后提示文案自动消失

单选框元素的 :indeterminate 伪类匹配有一个缺陷,那就是不被 IE 浏览器(包括 Edge)支持,使用时需要注意兼容性问题。

:indeterminate伪类与<progress>元素

对于 <progress> 元素,当没有设置值的时候,:indeterminate 伪类会匹配。例如:
progress:indeterminate {
  background-color: deepskyblue;
  box-shadow: 0 0 0 2px black;
}
结果,下面两段 HTML 的表现就出现了差异:
<progress min="1" max="100"></progress>
<progress min="1" max="100" value="50"></progress>
下图展示的是上述代码在 Firefox 浏览器下的表现。


图 6 不确定状态与<progress>元素匹配示意

可以看到,对于没有设置 value 属性值的 <progress> 元素,:indeterminate 伪类匹配了,而对于设置了 value 属性值的 <progress> 元素,:indeterminate 伪类则没有匹配。

<progress>元素的 :indeterminate 伪类匹配是从 IE10 浏览器开始支持的,在使用纯 CSS 自定义 <progress> 样式的时候,:indeterminate 伪类是必需的,可以用来改变 <progress> 元素的默认样式。

推荐阅读