清单计数器
对于“有序”清单来说,“编号”是相当重要的,除了使用默认的方式让编号依序呈现,也可以透过 counter() 或 counters() 的 CSS 函数控制与产生编号,这篇教学会介绍如何使用 counter() 和 counters(),以及对应的 counter-reset 和 counter-increment、counter-set 等样式属性。
更多参考:CSS 文字与清单计数 ( 函数类型 )
快速导览:
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
使用 counter()、counter-reset、counter-increment
counter() 是一个 CSS 的函数,是“所有元素”都可以使用的“计数器”功能,使用时需要先透过样式属性 counter-reset 和 counter-increment 定义计数器的名称和增加幅度,这两个样式属性的说明如下:
更多参考:CSS 文字与清单计数 ( 函数类型 )
| 计数器样式 | 默认值 | 说明 |
|---|---|---|
counter-reset |
0 | 定义计数器名称并重设数值 ( 类似变数 ),需要放在 counter-increment 外层。 |
counter-increment |
1 | 每出现一次对应名称的元素,就要增加多少数值。 |
定义 counter-reset 和 counter-increment 之后,就可以开始使用 counter 函数,使用时必须搭配“虚拟元素”和虚拟元素专用的“content”样式属性,下方的范例会把 div 里所有 h2 的前方加上计数器功能,因此 div 里有几个 h2,前方就会自动计算出数字。
<!-- HTML 程式碼 -->
<div>
<h2>apple</h2>
<h2>banana</h2>
<h2>coconut</h2>
<h2>oxxo.studio</h2>
<h2>papaya</h2>
</div>
<!-- CSS 程式碼 -->
<style>
div {
counter-reset: oxxo; /* 定義計數器名稱為 oxxo,重設數值為 0 */
}
h2 {
counter-increment: oxxo; /* div 裡每出現一次 h2,oxxo 數值就增加 1 */
margin: 0;
margin-left:20px;
}
h2::before {
content: counter(oxxo)". "; /* 使用計數器計算數字 */
}
</style>
如果要改变计数器的“初始值”或“增加的数值”,只需要定义 counter-reset 和 counter-increment 样式属性的“第二个数值”,如果没有定义,就会使用分别使用 0 和 1 作为默认值,下方范例会用两组 div,展示计数器从 100 开始,增加幅度分别是为 50 和 -15 的效果。
<!-- HTML 程式碼 -->
<div class="a">
<h2>apple</h2>
<h2>banana</h2>
<h2>coconut</h2>
<h2>oxxo.studio</h2>
<h2>papaya</h2>
</div>
<div class="b">
<h2>apple</h2>
<h2>banana</h2>
<h2>coconut</h2>
<h2>oxxo.studio</h2>
<h2>papaya</h2>
</div>
<!-- CSS 程式碼 -->
<style>
div {
counter-reset: oxxo 100;
margin: 10px;
border: 1px solid #000;
}
.a h2 {
counter-increment: oxxo 50; /* .a 裡面每出現一個 h2,計數器就增加 50 */
margin: 0;
margin-left:20px;
}
.b h2 {
counter-increment: oxxo -15; /* .b 裡面每出現一個 h2,計數器就減少 15 */
margin: 0;
margin-left:20px;
}
h2::before {
content: counter(oxxo)". ";
}
</style>
counter-set 设定清单数值
由于 counter-reset 会“重设”清单数值,无法处理单纯改变数值的状况,这时就需要透过 counter-set 进行“设定或修改清单数值”,counter-set 的默认值为 none,使用时需要先透过 counter-reset 建立计数器名称,接着只要在名称后方加上设定的数值就能修改清单数值,下方范例会将原本的 1~5 清单,从第六项开始改成 100~104。
<!-- HTML 程式碼 -->
<div>
<h2>apple</h2>
<h2>banana</h2>
<h2>coconut</h2>
<h2>oxxo.studio</h2>
<h2>papaya</h2>
<h2>pear</h2>
<h2>watermelon</h2>
<h2>corn</h2>
<h2>peach</h2>
<h2>orange</h2>
</div>
<!-- CSS 程式碼 -->
<style>
div {counter-reset: oxxo;} /* 定義計數器名稱為 oxxo,重設數值為 0 */
h2 {
counter-increment: oxxo; /* div 裡每出現一次 h2,oxxo 數值就增加 1 */
margin: 0;
margin-left:20px;
}
h2::before {
content: counter(oxxo)". "; /* 使用計數器計算數字 */
}
h2:nth-of-type(6) {counter-set: oxxo 100;}/* 第六項設為 100 */
</style>
除了修改单一数值,counter-set 也可以同时修改多个计数器数值,写法只需要利用“空白”分隔不同的计数器名称和数值,下方范例会同时修改两个清单里的数值,其中一个从 100 开始起算,另外一个从 -100 起算。
<!-- HTML 程式碼 -->
<div class="a">
<h2>apple</h2>
<h2>banana</h2>
<h2>coconut</h2>
<h2>oxxo.studio</h2>
<h2>papaya</h2>
</div>
<div class="b">
<h2>pear</h2>
<h2>watermelon</h2>
<h2>corn</h2>
<h2>peach</h2>
<h2>orange</h2>
</div>
<!-- CSS 程式碼 -->
<style>
.a {counter-reset: oxxo;} /* 定義計數器名稱為 oxxo,重設數值為 0 */
.b {counter-reset: xoox 10;} /* 定義計數器名稱為 xoox,重設數值為 10 */
h2 {margin: 0;}
.a h2 {
color: green;
counter-increment: oxxo; /* div 裡每出現一次 h2,oxxo 數值就增加 1 */
}
.b h2 {
color: blue;
counter-increment: xoox 10; /* div 裡每出現一次 h2,xoox 數值就增加 10 */
}
.a h2::before {content: counter(oxxo)". ";} /* 使用計數器計算數字 */
.b h2::before {content: counter(xoox)". ";} /* 使用計數器計算數字 */
div h2:nth-of-type(3){counter-set: oxxo 100 xoox -100;} /* 修改兩個計數器數值 */
</style>
清单元素使用 counter()
由于计数器 counter() 是透过虚拟元素的 content 显示数值,因此如果要在清单元素里使用计数器,建议先将原本的标记符号隐藏,避免相互干扰,或者使用 counters() 来实现修改清单标记的功能 ( 下方段落有详细介绍 ),下方范例将 counter-reset 放在 body,就可以让计数器的数值跨越不同的 div,让不同的清单中的数值可以接续下去。
<!-- HTML 程式碼 -->
<div>
<ul>
<li>apple</li>
<li>banana</li>
<li>coconut</li>
<li>oxxo.studio</li>
<li>papaya</li>
</ul>
</div>
<div>
<ul>
<li>apple</li>
<li>banana</li>
<li>coconut</li>
<li>oxxo.studio</li>
<li>papaya</li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
body {counter-reset: oxxo;}
div {
margin: 10px;
border: 1px solid #000;
}
ul {list-style: none;}
li {counter-increment: oxxo;}
li::before {content: counter(oxxo)". ";}
</style>
巢状计数
除了设定“单一”计数器名称,遇到“巢状清单”或“巢状结构”时,也可以设定“多组”计数器名称,再将每个名称分别套用到不同层的元素,就能实现巢状计数的功能,下方范例使用了一个“四层”的巢状清单,设定样式时分别设定每一层 li 对应不同的计数器,最后再将计数器数值组合,就可以实现巢状计数的效果。
<!-- HTML 程式碼 -->
<div>
<ul>
<li>apple</li>
<li>banana</li>
<li>oxxo.studio
<ul>
<li>pen</li>
<li>pencil</li>
<li>paper
<ul>
<li>red</li>
<li>blue</li>
<li>green
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
div {
margin: 10px;
border: 1px solid #000;
counter-reset: aa bb cc dd; /* 一次設定並重置多個計數器名稱 */
}
ul {list-style: none;} /* 隱藏清單標記 */
li {counter-increment: aa;} /* 第一層清單計數器使用 aa */
li li {counter-increment: bb;} /* 第二層清單計數器使用 bb */
li li li {counter-increment: cc;} /* 第三層清單計數器使用 cc */
li li li li {counter-increment: dd;} /* 第四層清單計數器使用 dd */
li::before {
content: counter(aa)"."counter(bb)"."counter(cc)"."counter(dd)". "; /* 組合多個計數器 */
}
</style>
使用 counters()
counters() 也是 CSS 的计数器函数,主要是提供具有“标记”和“巢状结构”的清单元素使用,让清单元素可以快速利用计数器设定标记,虽然也可以应用在非清单的元素,但使用时仍然都会以清单为主,counters() 具有三个参数,下方列出参数说明:
| 参数 | 说明 |
|---|---|
| counter-name | 自订义的计数器名称。 |
| string | 巢状结构中,上一层标记与下一层标记之间的连接符号,需要用引号包覆。 |
| counter-style | 标记的类型名称,参考“list-style-type 清单标记类型”。 |
counters() 的撰写语法:
li::before{
content: counters(counter-name, "string", counter-style);
}
下方范例透过 counters() 让巢状清单可以将计数器 0、1、2、3...的数字,转换成特定的标记,并按照一定的规则呈现巢状结构。
<!-- HTML 程式碼 -->
<div>
<ul class="a">
<li>apple</li><li>banana</li>
<li>oxxo.studio
<ul>
<li>red</li>
<li>yellow
<ul>
<li>HTML</li><li>CSS</li><li>Javascript</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div>
<ul class="b">
<li>apple</li> <li>banana</li>
<li>oxxo.studio
<ul>
<li>red</li>
<li>yellow
<ul>
<li>HTML</li><li>CSS</li><li>Javascript</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
ul {counter-reset: oxxo;} /* 設定計數器名稱並重置數值為 0 */
li {
list-style: none; /* 隱藏原本的清單標記 */
counter-increment: oxxo; /* 出現 li 就增加計數器的值 1 */
}
.a li::before {
content: counters(oxxo,'-',upper-alpha)'. '; /* 將計數器的數值對應到標記類型 */
color: red;
}
.b li::before {
content: counters(oxxo,'/',cjk-heavenly-stem)'. '; /* 將計數器的數值對應到標記類型 */
color: green;
}
</style>
counters() 改变清单标记
因为 counters() 是计数器,可以指定计数的“数字间隔”,透过不同的数字间隔对应到标记,就能做出“不连续的标记效果”,这也是单靠清单标记做不到的,下方的范例使用 aa 和 bb 两组计数器,aa 从 0 开始每次增加 2,bb 从 0 开始每次增加 3,转换成 upper-alpha 和 trad-chinese-formal 标记类型后,标记也会按照这个间隔呈现。
<!-- HTML 程式碼 -->
<div>
<ul class="a">
<li>apple</li>
<li>banana</li>
<li>oxxo.studio</li>
<li>papaya</li>
<li>orange</li>
<li>coconut</li>
<li>grap</li>
</ul>
</div>
<div>
<ul class="b">
<li>apple</li>
<li>banana</li>
<li>oxxo.studio</li>
<li>papaya</li>
<li>orange</li>
<li>coconut</li>
<li>grape</li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
margin: 10px;
}
.a {counter-reset: aa;}
.b {counter-reset: bb;}
.a li {
list-style: none;
counter-increment: aa 2; /* aa 間隔 2 增加 */
}
.b li {
list-style: none;
counter-increment: bb 3; /* bb 間隔 3 增加 */
}
.a li::before {
content: counters(aa,'',upper-alpha)'. ';
color: red;
}
.b li::before {
content: counters(bb,'',trad-chinese-formal)'. ';
color: green;
}
</style>
如果将上方范例的 CSS 加入 counter() 函数,就更能看出计数器数字和标记之间的关系。
div {
border: 1px solid #000;
margin: 10px;
}
.a {counter-reset: aa;}
.b {counter-reset: bb;}
.a li {
list-style: none;
counter-increment: aa 2;
}
.b li {
list-style: none;
counter-increment: bb 3;
}
.a li::before {
content: counters(aa,'',upper-alpha)'('counter(aa)'). '; /* 加入 counter() */
color: red;
}
.b li::before {
content: counters(bb,'',trad-chinese-formal)'('counter(bb)'). '; /* 加入 counter() */
color: green;
}
小结
counter() 或 counters() 是两个相当好用的 CSS 计数器函数,可以快速修改清单标记的样式 ( 其实所有元件都可以,只是比较不会这么做 ),如果熟练应用,就可以不需要透过 JavaScript 辅助,也可以快速实现清单标记的各种效果。
微信扫码关注
抖音扫码关注