计数器是一种特殊的数字跟踪器,通常用于为CSS列表项自动编号,早期无序列表ul和有序列表ol元素定义时,会自动添加counter()
计数器,列表也会自动递增序号,属性都会取默认值
CSS计数器只能跟content
属性在一起的时候才有作用,而content
属性专门用在before
/after
伪元素上。
于是,就有了,“计数器↔伪元素↔content属性”的铁三角关系。
counter-reset (可以同时声明多个计数器)
counter-reset: name (initialValue||0);
counter-increment 递增变量(计数的变化值)
counter-increment: name (changeValue||1)
CSS的计数器的计数是有一套规则的,称为“ 普照规则”:普照源(counter-reset)唯一,每普照(counter-increment)1次,普照源增加1次计数值。
A. 普通普照
"counter"
>
counter-increment普照了p标签,counter-reset值增加1,于是计数从设置的初始值0变成了1,reset就是这里的计数器,伪元素content值counter(reset)就是1
B. 普照自身 (counter-increment直接设置在伪元素上),结果同上
"counter"
>
如果父元素和子元素都被counter-increment普照1遍,结果应该是计数器普照两次,结果为2
父元素没有普照,重置默认值0,父元素有2个孩子。孩子自身都接受普照。两个孩子的计数值是?
.counter {
counter-reset: reset 0;
font-size: 24px;
}
.counter:before,
.counter:after {
content: counter(reset);
counter-increment: reset;
}
<p class="counter"> vs p>
计数器的数值变化遵循HTML渲染顺序,遇到一个increment计数器就变化,什么时候counter输出就输出此时的计数值。
content: counter(name, style) // 1,2,3
content: counters(name, string, style); // 显示嵌套计数,如1.1,1.2,1.3……
string :字符串,子序号的连接符https://codepen.io/airen/pen/YzVBVrG
style: 支持关键字 list-style-type,递增和递减不一定都是数字, 可以是英文字母或其他
在同一层级中,可以通过重复声明相同名字的计数器来打断(或者说是覆盖)之前的计数,重新开始。
<div class="level1">
<div class="level1-item">foodiv>
<div class="level1-item">bardiv>
<div class="level1-item break">bazdiv>
<div class="level1-item">quxdiv>
div>
<style>
.level1 {
counter-reset: level1;
}
.break {
counter-reset: level1;
}
.level1-item:before {
content: counter(level1, upper-roman) '.';
counter-increment: level1 1;
}
style>
“普照源是唯一的” => “一个容器里的普照源(reset)是唯一的”
想实现嵌套,必须让每一个列表容器拥有一个“普照源”,通过子辈对父辈的counter-reset
重置、配合counters()
方法才能实现计数嵌套效果。
html:
<div class="reset">
<div class="counter">text1
<div class="reset">
<div class="counter">text1-1div>
<div class="counter">text1-2
<div class="reset">
<div class="counter">text1-2-1div>
<div class="counter">text1-2-2div>
<div class="counter">text1-2-3div>
div>
div>
<div class="counter">text1-3div>
div>
div>
<div class="counter">text2div>
<div class="counter">text3
<div class="reset">
<div class="counter">text3-1div>
div>
div>
div>
css:
如果不保证一个容器里的普照源唯一,打乱html顺序:
<div class="reset">
<div class="counter">text1div>
<div class="reset">
<div class="counter">text1-1div>
<div class="counter">text1-2
<div class="reset">
<div class="counter">text1-2-1div>
<div class="counter">text1-2-2div>
<div class="counter">text1-2-3div>
div>
div>
<div class="counter">text1-3div>
div>
<div class="counter">text2div>
<div class="counter">text3div>
div>
这里的reset与上面的counter是兄弟关系,而不是父子关系。一个容器的reset的唯一的,一旦子元素出现reset,会改变整个容器的嵌套关系
::marker
是CSS中新出的一种伪元素,用来匹配列表项中的“标记盒子”(设置为display:list-item
的块级元素,除主块级盒子外有一个附加盒子),并可以设置标记盒子里面的内容以及与字符显示相关的UI。
例如大家比较熟悉的元素,就可以直接使用
::marker
伪元素改变项目符号颜色、字号字体、甚至内容
<style>
li {
display: list-item;
}
li::marker {
content: "(" counter(list-item) ")";
}
style>
<ul>
<li>textli>
<li>textli>
<li>textli>
ul>
有时候可能需要CSS变量作为字符在页面中呈现,CSS变量直接作为content属性值是没有任何效果的
/* 无效 */
.bar::before {
content: var(--percent);
}
虽然content属性本身不支持变量,但是counter-reset属性后面的计数器初始值是支持的,可以通过counter和content配合使用达到效果:
.bar::before {
counter-reset: progress var(--percent);
content: counter(progress);
}