计数是 Web应用程序中无处不在的任务 。 您有多少未读电子邮件? 您的待办事项列表上还有多少个未选中的任务? 购物车中装有多少种甜甜圈口味? 所有这些都是用户值得回答的关键问题。
因此,本篇文章将向您展示如何使用CSS计数器 计算双向状态的元素 ,这些元素构成了大多数用户控件,例如复选框和文本输入。
您需要首先使用CSS定位这些状态 ,这可以通过允许我们做到这一点的伪类和HTML属性来实现。 继续尝试该想法,并探索可以动态指示元素状态变化的不同伪类。
我们将从最简单的复选框开始。
1.复选框
复选框被打勾时进入“已检查”状态。 :checked
伪类指示已检查状态 。
<input type=checkbox> checkbox #1<br>
<input type=checkbox> checkbox #2<br>
<input type=checkbox> checkbox #3<br>
<br>Checked: <b id=tickedBoxCount></b>
<br>Unchecked: <b id=unTickedBoxCount></b>
::root{
counter-reset: tickedBoxCount, unTickedBoxCount;
}
input[type='checkbox']{
counter-increment: unTickedBoxCount;
}
input[type='checkbox']:checked{
counter-increment: tickedBoxCount;
}
#tickedBoxCount::before{
content: counter(tickedBoxCount);
}
#unTickedBoxCount::before{
content: counter(unTickedBoxCount);
}
如我之前所说,这种情况非常简单。 我们在根元素上设置了两个计数器,并为每个复选框分别增加了两个计数器的两个状态。 然后,使用content
属性将计数器值显示在指定的位置 。
如果您想更好地了解CSS计数器的工作方式 ,请查看我们以前的文章 。
在下面,您可以看到最终结果。 当您选中并取消选中复选框时,“已检查”和“未检查”计数器的值将实时修改 。
2.文字输入
我们还可以计算出有多少文本输入已被填充 ,以及有多少用户已留空 。 该解决方案不会像上一个解决方案那么简单,因为与复选框不同, 文本输入在填充时没有伪类进行标记。
因此,我们需要找到一条替代路线。 有一个伪类,它指示元素何时具有占位符文本 ; 它称为:placeholder-shown
。
如果在文本输入中使用占位符,则可以知道输入字段何时为空。 当用户尚未在其中键入任何内容时,就会发生这种情况,因为占位符会在这种情况下消失。
<input type=text placeholder='placeholder text'><br>
<input type=text placeholder='placeholder text'><br>
<input type=text placeholder='placeholder text'><br>
<br> Filled: <b id=filledInputCount></b>
<br> Empty: <b id=emptyInputCount></b>
::root{
counter-reset: filledInputCount, emptyInputCount;
}
input[type='text']{
counter-increment: filledInputCount;
}
input[type='text']:placeholder-shown{
counter-increment: emptyInputCount;
}
#filledInputCount::before{
content: counter(filledInputCount);
}
#emptyInputCount::before{
content: counter(emptyInputCount);
}
结果与前一个类似-当我们在输入字段中添加文本或从中删除文本时,这两个计数器会自动递增和递减 。
3.细节
元素的备用状态不一定总是仅由伪类指示。 可能会有HTML属性完成这项工作 ,例如<details>
元素。
<details>
元素显示其<summary>
子元素的内容 。 当用户单击时, <details>
元素的其他内容变为可见 。 请注意, <summary>
元素始终必须在<details>
的子元素中排在第一位 。
因此, <details>
具有两个状态 :打开和关闭。 打开状态由元素中存在open
HTML属性指示。 此属性可以使用其属性选择器在CSS中定位。
<details>
<summary>Q1: question #1</summary>
<p>answer #1</p>
</details>
<details>
<summary>Q2: question #2</summary>
<p>answer #2</p>
</details>
<details>
<summary>Q3: question #3</summary>
<p>answer #3</p>
</details>
<br>
<br> Open: <b id=openDetailCount></b>
<br> Closed: <b id=closedDetailCount></b>
::root{
counter-reset: openDetailCount, closedDetailCount;
}
details{
counter-increment: closedDetailCount;
}
details[open]{
counter-increment: openDetailCount;
}
#closedDetailCount::before{
content: counter(closedDetailCount);
}
#openDetailCount::before{
content: counter(openDetailCount);
}
结果又是两个实时CSS计数器 :打开和关闭。
4.单选按钮
计算单选按钮需要另一种方法。 当然,我们可以使用用于复选框的:checked
伪类。 但是,单选按钮的用法与复选框不同 。
单选按钮应成组放置 。 用户只能在组中选择一个。 每个组充当一个单元。 单选按钮组可以具有的两种状态是选择了一个按钮或没有 选择 任何一个 。
因此,我们不应按单个按钮计数单选按钮,而应按按钮组计数。 为此,我们使用:nth-of-type
选择器 。 稍后再解释; 让我们先来看代码。
<input type=radio name='radio-1'>radio-1.1
<input type=radio name='radio-1'>radio-1.2
<input type=radio name='radio-1'>radio-1.3
<br>
<input type=radio name='radio-2'>radio-2.1
<input type=radio name='radio-2'>radio-2.2
<input type=radio name='radio-2'>radio-2.3
<br>
<input type=radio name='radio-3'>radio-2.1
<input type=radio name='radio-3'>radio-2.2
<input type=radio name='radio-3'>radio-2.3
<br>
<br> Selected: <b id=selectedRadioCount></b>
<br> Unselected: <b id=unSelectedRadioCount></b>
我们需要为同一组中的单选按钮分配相同的名称 。 上面的代码中的每个组内部都有三个单选按钮。
::root{
counter-reset: selectedRadioCount, unSelectedRadioCount;
}
input[type='radio']:nth-of-type(3n){
counter-increment: unSelectedRadioCount;
}
input[type='radio']:nth-of-type(3n):checked{
counter-increment: selectedRadioCount;
}
input[type='radio']:not(:nth-of-type(3n)):checked{
counter-increment: unSelectedRadioCount -1 selectedRadioCount;
}
#selectedRadioCount::before{
content: counter(selectedRadioCount);
}
#unSelectedRadioCount::before{
content: counter(unSelectedRadioCount);
}
上面代码段中的前三个样式规则与我们应用于复选框的规则相同,除了我们不定位每个单选按钮, 而是定位每个组中的最后一个单选按钮 ,这是本例中的第三个( :nth-of-type(3n)
)。 因此,我们不算所有单选按钮,而是每组只算一个 。
但是,由于我们尚未给出任何计算组中其他两个单选按钮的规则,因此这不会为我们提供正确的实时结果。 如果选中其中之一,则应将其计数并且未经检查的结果应同时减少。
这就是为什么我们在针对组中其他两个单选按钮的最后一个样式规则中的unSelectedRadioCount
之后添加-1
值的原因。 选中其中之一时, -1
将减少未选中的结果 。
计数的位置
只有在完成计数后 ,即在处理了所有要计数的元素之后,才能看到正确的结果。 这就是为什么我们需要将元素放置在其中,以便仅在 HTML源代码中要计数的元素之后显示计数器。
您可能不希望在元素下方显示计数器,而在页面其他位置显示计数器。 在这种情况下,您需要使用CSS属性(例如translate
, margin
或position
来重新定位计数器 。
但是,我的建议是使用CSS网格,以便您可以独立于HTML源代码中其元素的顺序来创建页面的布局。 例如,您可以轻松地创建一个网格,将计数器放在输入字段的上方或旁边。