1. 引言
本规范定义了 ::marker 伪元素, 生成标记的 列表项 显示类型, 以及几个控制标记位置和样式的属性。
它还定义了 计数器, 计数器是特殊的数字对象, 通常用于生成标记的默认内容。
< style > li :: marker { content : "(" counter( list-item , lower-roman ) ")" ; } li { display : list-item ; } </ style > < ol > < li > 这是第一项。< li > 这是第二项。< li > 这是第三项。</ ol >
这将产生类似于以下内容:
(i) 这是第一项。 (ii) 这是第二项。 (iii) 这是第三项。
注意: 请注意,这个示例的内容比在HTML中通常需要的内容要冗长得多, 因为用户代理的默认样式表处理了大部分必要的样式。
通过后代选择器和子选择器, 可以根据嵌套列表的深度指定不同的标记类型。
1.1. 值定义
本规范遵循 CSS属性定义约定, 来自 [CSS2], 使用 值定义语法, 来源于 [CSS-VALUES-3]。 本规范未定义的值类型在 CSS 值与单位[CSS-VALUES-3]中定义。 与其他CSS模块结合可能会扩展这些值类型的定义。
除了在其定义中列出的属性特定值之外, 本规范定义的所有属性 也接受 CSS广域关键字 作为它们的属性值。 为了可读性,它们没有被显式重复。
2. 声明列表项
列表项是任何其 display 属性设置为 list-item 的元素。 列表项 生成 ::marker 伪元素;没有其他元素这样做。 此外,列表项 自动递增一个隐含的 list-item 计数器(见 § 4.6 隐式列表项计数器)。
3. 标记
列表项 显示类型的定义特征是其 标记, 是帮助标示每个 列表项 在列表中开始的符号或序数。 在CSS布局模型中,列表项 标记由与每个 列表项 关联的 标记盒 表示。 此 标记 的内容可以通过在 列表项 上设置 list-style-type 和 list-style-image 属性来控制,并通过为其 ::marker 伪元素分配属性。
3.1. ::marker 伪元素
标记盒由 ::marker 伪元素生成,作为列表项的第一个子元素,位于 列表项 之前,::before 伪元素(如果元素上存在)。 它的内容由§ 3.2 生成标记内容中定义的内容填充。
< style > p { margin-left : 12 em ; } p . note { display : list-item ; counter-increment : note-counter ; } p . note :: marker { content : "备注 " counter( note - counter ) ":" ; } </ style > < p > 这是本文档的第一段。< p class = "note" > 这是一篇非常简短的文档。< p > 这是结束。
它应该呈现为如下内容:
这是第一段 在这个文档中。 备注 1: 这是一个非常简短的 文档。 这是结束。
< style > p { margin-left : 8 em } /* 为计数器留出空间 */ li { list-style-type : lower-roman ; } li :: marker { color : blue ; font-weight : bold ; } </ style > < p > 这是一个较长的前导段落 ...< ol > < li > 这是第一项。< li > 这是第二项。< li > 这是第三项。</ ol > < p > 这是一个较长的后续段落 ...
前面的文档应该呈现如下:
这是一个较长的 前导段落 ... i. 这是第一项。 ii. 这是第二项。 iii. 这是第三项。 这是一个较长的 后续段落 ...
之前唯一的标记样式方法是通过继承;需要将所需的标记样式放在列表项上,然后在列表项实际内容周围的包装元素上还原该样式。
标记盒仅存在于列表项上:在任何其他元素上,::marker 伪元素的content 属性必须计算为none,这将抑制其创建。
3.1.1. 适用于 ::marker 的属性
所有属性都可以设置在::marker 伪元素上,并将具有计算值;但是,只有以下CSS属性实际上适用于标记盒:
- text-combine-upright、unicode-bidi和direction属性(参见[CSS-WRITING-MODES-3])
- content属性(参见§ 3.2 生成 标记内容,如下)
- 所有动画和过渡属性(参见[CSS-ANIMATIONS-1]和[CSS-TRANSITIONS-1])
预计未来的规范将扩展此属性列表;然而,目前标记盒布局尚未完全定义, 因此仅允许这些属性。
在标记盒中,其他属性在作者源的级联中不得 产生效果。用户代理可以将这些属性视为不适用,或者通过设置用户代理源 !important规则来强制其值。 然而,适用于文本的可继承属性可以设置在::marker伪元素上:这些属性将继承并对其文本内容生效。
- white-space、text-transform、letter-spacing(参见[CSS-TEXT-3])
- 所有字体属性(参见[CSS-FONTS-3]及其后续版本)
- color属性(参见[CSS-COLOR-3])
用户代理必须将以下规则添加到其默认样式表:
::marker, ::before::marker, ::after::marker { unicode-bidi: isolate; font-variant-numeric: tabular-nums; white-space: pre; text-transform: none; }
注意: 尽管::marker 伪元素可以表示标记盒的::before或::after
伪元素,复合选择器::marker,它扩展为*::marker
[SELECTORS-4],不会选择这些标记—
white-space: pre 的行为并不完全正确; text-space-collapse: preserve-spaces + text-space-trim: discard-after 可能更接近所需的行为。 请参见问题 4448 和问题 4891中的讨论。
3.2. 生成标记内容
标记盒marker box的内容由第一个真实的条件决定:
- content 在::marker 本身不为normal
- 标记盒的内容由marker box的content属性定义,完全与::before相同。
- list-style-image 在源元素上定义了一个标记图像
- 标记盒包含一个匿名 行内 替换元素,表示指定的标记图像,后面跟着一个由单个空格(U+0020 SPACE)组成的文本序列。
- list-style-type 在源元素上定义了一个标记字符串
- 标记盒包含一个由指定的标记字符串组成的文本序列。
- 否则
- 标记盒没有内容,并且::marker不会生成一个盒子。
此外,用户代理可以将任何保留的强制换行转换为空格或丢弃。
3.3. 图像标记:list-style-image 属性
名称: | list-style-image |
---|---|
值: | <image> | none |
初始值: | none |
适用对象: | 列表项 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 关键字none或计算的<image> |
标准顺序: | 按语法 |
动画类型: | 离散 |
指定了标记图像, 该图像用于填充列表项的 标记,当其内容为正常时。 可用值如下:
- <image>
- 如果<image> 代表一个有效图像,则指定元素的标记图像为<image>。 否则,元素没有标记图像。
- none
- 该元素没有标记图像。
li{ list-style-image : url ( "http://www.example.com/ellipse.png" ) }
3.4. 基于文本的标记:list-style-type 属性
名称: | list-style-type |
---|---|
值: | <counter-style> | <string> | none |
初始值: | disc |
适用对象: | 列表项 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 指定值 |
标准顺序: | 按语法 |
动画类型: | 离散 |
指定了标记字符串, 该字符串用于填充列表项的标记,当其内容值为正常且没有标记图像时。 可用值如下:
- <counter-style>
-
指定元素的标记字符串为
作为指定列表项计数器的值,使用指定的<counter-style>。
具体来说, 标记字符串是 生成计数器表示的列表项计数器值的结果, 使用指定的<counter-style>, 以指定的前缀开头, 并以指定的<counter-style>的后缀结尾。 如果指定的<counter-style> 不存在,则假定为十进制。
- <string>
- 元素的标记字符串是指定的<string>。
- none
- 元素没有标记字符串。
ul{ list-style-type : "★" ; } /* 将标记设置为“星号”字符 */ p.note{ display : list-item; list-style-type : "Note: " ; list-style-position : inside; } /* 为注释段落赋予标记,由字符串“Note: ”组成 */ ol{ list-style-type : upper-roman; } /* 将所有有序列表设置为使用上罗马计数样式 */ (在计数样式规范中定义 [[CSS-COUNTER-STYLES]]) */ ul{ list-style-type : symbols ( cyclic'○' '●' ); } /* 设置所有无序列表项交替使用空心和实心圆作为标记。 */ ul{ list-style-type : none; } /* 完全抑制标记,除非指定有效图像的list-style-image。 */
3.5. 标记位置:list-style-position 属性
名称: | list-style-position |
---|---|
值: | inside | outside |
初始值: | outside |
适用对象: | 列表项 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 关键字,但见正文 |
标准顺序: | 按语法 |
动画类型: | 离散 |
此属性决定::marker是以内联方式呈现, 还是定位在列表项的外部。 值如下:
- inside
- 没有特殊效果。 (标记在::marker 是列表项内容的一个内联元素。)
- outside
-
如果列表项是块容器:
则标记框是一个块容器,并位于主块框的外部;
然而,列表项标记相对于浮动元素的位置未定义。
CSS并未指定标记框的精确位置
或其在绘制顺序中的位置,
但要求将其放置在行起始的一侧,
使用由marker-side指示的框的书写模式。
标记框相对于主块框的边框是固定的,
并且不会随主框的内容滚动。
如果元素的溢出属性设置为其他值而非可见,则用户代理可能会隐藏标记。
(此允许在未来可能会改变。)
标记框的大小或内容可能会影响
主块框的高度
和/或其首行框的高度,
并在某些情况下可能导致新行框的创建;
此交互关系也未定义。
另外,outside可以将标记布局为主内联框的前一个兄弟。
<style> ul.compact { list-style: inside; } ul { list-style: outside; } </style> <ul class=compact> <li>第一个“inside”列表项</li> <li>第二个“inside”列表项</li> </ul> <hr> <ul> <li>第一个“outside”列表项</li> <li>第二个“outside”列表项</li> </ul>
上述示例可能会格式化为:
* 第一个 "inside" 列表 项位于最前 * 第二个 "inside" 列表 项位于第二 ======================== * 第一个 "outside" 列表 项位于最前 * 第二个 "outside" 列表 项位于第二
3.6. 样式标记:list-style 简写属性
名称: | list-style |
---|---|
值: | <'list-style-position'> || <'list-style-image'> || <'list-style-type'> |
初始值: | 见各个属性 |
适用对象: | 列表项 |
继承: | 见各个属性 |
百分比: | 见各个属性 |
计算值: | 见各个属性 |
动画类型: | 见各个属性 |
标准顺序: | 按语法 |
属性list-style是用于设置三个属性的简写形式:list-style-type、list-style-image和list-style-position,可以在样式表中一次性设置。
ul{ list-style : upper-roman inside} /* 任何 UL */ ul ul{ list-style : circle outside} /* 任何 UL 的子 UL */
在简写中使用none的值可能会产生歧义, 因为none是list-style-image和list-style-type的有效值。 为了解决这种歧义, 简写中的none值必须应用于未通过简写设置的两个属性中的一个。
list-style : none disc; /* 将图像设置为 "none",类型设置为 "disc"。 */ list-style: noneurl ( bullet.png ); /* 将图像设置为 "url(bullet.png)",类型设置为 "none"。 */ list-style: none; /* 将图像和类型都设置为 "none"。 */ list-style: none discurl ( bullet.png ); /* 语法错误 */
注意: <counter-style> 的值可以在list-style-type中创建语法歧义。 由于这些值最终是<custom-ident>值, 所以在[CSS-VALUES-3]中的解析规则适用。
li
),
他们应该谨慎行事。
考虑以下规则:
ol.alpha li{ list-style : lower-alpha; } ul li{ list-style : disc; }
上述示例不会按预期工作。
如果将一个ul
嵌套在一个ol class=alpha中,
第一个规则的特定性会使ul
的
列表项使用lower-alpha样式。
ol.alpha > li{ list-style : lower-alpha; } ul > li{ list-style : disc; }
这些规则按预期工作。
ol.alpha{ list-style : lower-alpha; } ul{ list-style : disc; }
这些更好, 因为继承将把list-style值传递给列表项。
3.7. marker-side 属性
名称: | marker-side |
---|---|
值: | match-self | match-parent |
初始值: | match-self |
适用对象: | 列表项 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 指定的关键字 |
标准顺序: | 按语法 |
动画类型: | 离散 |
marker-side 属性指定了是否一个外部标记框的位置是基于列表项本身的方向性(即它的原始元素)还是列表容器的方向性(即原始元素的父元素)。在第一种情况下,标记的位置可以在同一列表的项目之间变化,基于每个列表项单独分配的方向性;在第二种情况下,所有标记将对齐在同一侧,由整体列表分配的方向性决定。
- match-self
- 标记框 是使用::marker的原始元素的方向性来定位的。
- match-parent
- 标记框 是使用::marker的原始元素的父元素的方向性来定位的。
以下两个示例渲染是由以下HTML生成的,唯一的区别是列表上的marker-side的值:
< ul > < li > 英语一< li dir = rtl > 阿拉伯语< li > 英语三< li dir = rtl > 阿拉伯语三</ ul >
match-self | match-parent |
---|---|
* 英语一 阿拉伯语 * * 英语三 阿拉伯语三 * |
* 英语一 * 阿拉伯语 * 英语三 * 阿拉伯语三 |
为了使标点符号在标记内正确排序, 还需要考虑父元素的方向值。 <https://github.com/w3c/csswg-drafts/issues/4202>
有关重命名关键字和与 list-style-position 合并 的问题仍在开放中。
4. 使用计数器进行自动编号
计数器 是一个特殊的数字跟踪器,用于自动编号 CSS 中的列表项等多种用途。每个元素都有一个零或多个计数器的集合,这些计数器以类似于继承属性值的方式通过文档树继承。计数器 具有一个 名称 和 创建者,用于识别计数器,并且有一个整数 值。它们通过 计数器属性 counter-increment、counter-set 和 counter-reset 创建和操作,并与 counter() 和 counters() 函数表示法一起使用。
计数器在 CSS 语法中通过 <counter-name> 类型引用,表示其名称为 <custom-ident>。<counter-name> 名称不能与关键字 none 匹配;这样的标识符被认为是无效的 <counter-name>。
在给定元素上解析计数器值是一个多步骤的过程:
-
现有计数器从前面的元素继承。
-
新计数器被实例化(counter-reset)。
-
计数器值被递增(counter-increment)。
-
计数器值被显式设置(counter-set)。
-
计数器值被使用(counter()/counters())。
用户代理可能对计数器的最大值或最小值有实现特定的限制。如果计数器重置、设置或递增将使值超出该范围,则必须将值限制在该范围内。
4.1. 创建计数器:counter-reset 属性
名称: | counter-reset |
---|---|
值: | [ <counter-name> <integer>? ]+ | none |
初始: | none |
适用对象: | 所有元素 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 关键字 none 或一个列表,每个项是标识符和整数的配对 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
用户代理预计将在所有媒体上支持此属性,包括非视觉媒体。
counter-reset 属性实例化了元素上的新计数器,并将其设置为指定的整数值。其值定义如下:
- none
- 此元素不创建任何新计数器。
- <counter-name> <integer>?
- 实例化一个给定<counter-name>的计数器,其起始值为给定的<integer>,默认为0。
h1{ counter-reset : section-1 } h1{ counter-reset : imagenum99 }
将仅重置imagenum。要重置两个计数器,它们必须一起指定:
H1{ counter-reset : section-1 imagenum99 }
相同的原则适用于counter-set 和 counter-increment 属性。请参见[css-cascade-4]。
如果在属性值中出现多个相同的<counter-name> 实例,仅最后一个会被尊重。
4.2. 操作计数器值:counter-increment 和 counter-set 属性
名称: | counter-increment |
---|---|
值: | [ <counter-name> <integer>? ]+ | none |
初始: | none |
适用对象: | 所有元素 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 关键字 none 或一个列表,每个项是标识符与整数的配对 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
用户代理预计将在所有媒体上支持此属性,包括非视觉媒体。
名称: | counter-set |
---|---|
值: | [ <counter-name> <integer>? ]+ | none |
初始: | none |
适用对象: | 所有元素 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 关键字 none 或一个列表,每个项是标识符与整数的配对 |
规范顺序: | 按语法 |
动画类型: | 按计算值类型 |
用户代理预计将在所有媒体上支持此属性,包括非视觉媒体。
counter-increment 和 counter-set 属性用于操作现有计数器的值。只有在元素上不存在给定名称的计数器时,它们才会实例化新的计数器。它们的值定义如下:
- none
- 此元素不会更改任何计数器的值。
- <counter-name> <integer>?
- 为元素上命名的计数器设置(用于counter-set)或递增(用于counter-increment)其值,值为指定的<integer>。如果省略<integer>,则默认为1(用于counter-increment)或0(用于counter-set)。
如果元素上当前不存在给定名称的计数器,元素将实例化一个新计数器,起始值为0,然后设置或递增其值。
此示例演示了如何对章节和部分进行编号,格式为 "第1章"、"1.1"、"1.2" 等。
h1 : :before{ content : "Chapter " counter ( chapter) ". " ; counter-increment : chapter; /* Add 1 to chapter */ counter-reset: section; /* Set section to 0 */ } h2::before{ content : counter ( chapter) "." counter ( section) " " ; counter-increment : section; }
如果在属性值中出现多个相同的<counter-name>实例,它们会按顺序处理。因此,递增将累加,但只有最后一个设置值会生效。
4.3. 嵌套计数器和作用域
计数器是“自我嵌套”的;在一个元素上实例化一个新的计数器,该计数器从其父元素继承了同名的计数器,会在现有计数器内部创建一个同名的新计数器。这在HTML列表等场景中非常重要,因为列表可以嵌套在列表内部,嵌套的深度不受限制:为每个级别定义唯一命名的计数器是不可能的。counter() 函数仅检索元素上给定名称的最内层计数器,而counters() 函数则使用包含该元素的所有给定名称的计数器。
因此,作用域 的计数器从文档中第一个实例化该计数器的元素开始,并包括该元素的后代和后继兄弟元素及其后代。然而,它不包括任何在后续兄弟元素上通过counter-reset创建的同名计数器作用域中的元素,这允许此类显式计数器实例化遮蔽早期的兄弟元素。
请参见§ 4.4 创建和继承计数器,以了解有关计数器及其值作用域的确切规则。
ol{ counter-reset : item} li{ display : block} li::before{ content : counter ( item) ". " ; counter-increment : item}
在此示例中,一个ol将创建一个计数器,所有ol的子元素都将引用该计数器。
如果我们用nth 实例表示item计数器为 itemn,则以下 HTML 片段将使用指定的计数器。
<ol>
item0 被创建,设置为0
<li>
item0 被递增到1<li>
item0 被递增到2
<ol>
item1 被创建,设置为0,嵌套在 item0 内
<li>
item1 被递增到1<li>
item1 被递增到2<li>
item1 被递增到3
<ol>
item2 被创建,设置为0,嵌套在 item1 内
<li>
item2 被递增到1</ol>
<li>
item1 被递增到4
<ol>
item3 被创建,设置为0,嵌套在 item1 内
<li>
item3 被递增到1</ol>
<li>
item1 被递增到5</ol>
<li>
item0 被递增到3<li>
item0 被递增到4</ol>
<ol>
item4 被创建,设置为0
<li>
item4 被递增到1<li>
item4 被递增到2</ol>
4.4. 创建和继承计数器
文档中的每个元素或伪元素都有一组(可能为空)的计数器,这些计数器在该元素的作用域内,或者通过从另一个元素继承,或者通过在元素上直接实例化。这些计数器表示为一个集合,每个值是一个元组,包括: 字符串(表示计数器的名称), 一个元素(表示计数器的创建者), 和一个整数(表示计数器的值)。 该集合中给定名称的最新计数器表示该名称的最内层计数器。
4.4.1. 继承计数器
-
让element counters表示element自身的CSS计数器集合, 复制element的父元素的CSS计数器集合。
-
让sibling counters是element的前一个兄弟元素的CSS计数器集合(如果存在), 否则为一个空的CSS计数器集合。
对于每个 counter 的sibling counters, 如果element counters中尚不存在同名计数器, 将counter的副本附加到element counters。
-
让value source是CSS计数器集合,该集合为element在树顺序中紧接着element的元素。
对于每个 source counter 的value source, 如果element counters 包含同名且具有相同名称和创建者的计数器, 则将该计数器的值设置为source counter的值。
<ul style='counter-reset: example 0;'> <li id='foo' style='counter-increment: example;'> foo <div id='bar' style='counter-increment: example;'>bar</div> </li> <li id='baz'> baz </li> </ul>
请记住,树顺序将文档树转换为有序列表,其中一个元素在其子元素之前,子元素在其下一个兄弟元素之前。换句话说,对于像HTML这样的语言,它是解析器在读取文档时遇到起始标签的顺序。
在这里,ul
元素建立了一个名为example的新计数器,并将其值设置为0。#foo元素作为ul
的第一个子元素,继承了此计数器。它的父元素也是其在树顺序中紧接着的元素,因此它继承了值0,然后立即将值递增到1。
对于#bar元素也是如此。它从#foo继承了example计数器,并且也继承了其值1,然后将其递增到2。
然而,#baz元素稍有不同。它从前一个兄弟元素#foo继承了example计数器。然而,与其一起继承的并不是从#foo获得的值1,而是从#bar,这是在树顺序中前一个元素获得的值2。
这种行为允许在整个文档中使用单个计数器,不断递增,而无需担心文档的嵌套结构。
注意:计数器继承与常规CSS 继承一样,在[DOM]上下文中对“扁平化元素树”操作。
4.4.2. 实例化计数器
4.5. 不生成盒子的元素中的计数器
不生成盒子的元素(例如,display 设置为 none,或一个伪元素的content 设置为 none)无法设置、重置或递增计数器。计数器属性在此类元素上仍然有效,但必须没有效果。
注意:隐藏元素的其他方法,例如将visibility设置为 ,仍然会导致元素生成一个盒子,因此这里不例外。
是否一个替换元素的后代(如HTML
option
,或SVG
rect
)可以设置、重置或递增计数器是未定义的。
注意:由于实现之间缺乏互操作性,对于替换元素后代的行为目前是未定义的。
4.6. 隐式 list-item 计数器
除了作者在样式中显式定义的计数器外,列表项会自动递增一个特殊的 list-item 计数器,该计数器用于生成默认的标记字符串(见list-style-type)。
具体而言,除非counter-increment属性显式指定了不同的递增值,否则每个列表项必须将该list-item计数器递增1,同时正常递增计数器(就像该列表项在其counter-increment值中附加了list-item 1一样,包括可能导致实例化一个新的计数器等副作用)。这不会影响counter-increment的指定或计算值。
但是,由于自动list-item递增在列表项的counter-increment明确提及list-item计数器时并不会发生,li { counter-increment: list-item 2; }将如所指定递增list-item 2,而不是如list-item 1那样递增3。
这还允许通过显式覆盖来关闭自动list-item计数器递增,例如counter-increment: list-item 0;。
在所有其他方面,list-item 计数器的行为与其他任何计数器相同,作者可以使用和操作它来调整列表项样式或用于其他目的。
在以下示例中,列表被修改为按二的倍数计数:
ol.evens > li { counter-increment: list-item 2; }
三项列表将呈现为
2. 第一个项目 4. 第二个项目 6. 第三个项目
用户代理和主机语言应确保list-item计数器值默认反映主机语言语义规定的底层数值,在其用户代理样式表和表现提示样式映射中设置列表项样式。参见,例如附录 A: HTML 的示例样式表。
ol > li::marker { content: counters(list-item,'.') '.'; }
使用此规则的嵌套列表将呈现为
1. 第一个顶级项目 5. 第二个顶级项目,值=5 5.3. 第一个第二级项目,列表开始=3 5.4. 第二个第二级项目,列表开始=3 5.4.4. 第一个第三层级项目,倒序列表 5.4.3. 第二个第三层级项目,倒序列表 5.4.2. 第三个第三层级项目,倒序列表 5.4.1. 第四个第三层级项目,倒序列表 5.5. 第三个第二级项目,列表开始=3 6. 第三个顶级项目
给定标记如
<ol> <li>第一个顶级项目 <li value=5>第二个顶级项目,值=5 <ol start=3> <li>第一个第二级项目,列表开始=3 <li>第二个第二级项目,列表开始=3 <ol reversed> <li>第一个第三层级项目,倒序列表 <li>第二个第三层级项目,倒序列表 <li>第三个第三层级项目,倒序列表 <li>第四个第三层级项目,倒序列表 </ol> </ol> <li>第三个第二级项目,列表开始=3 <li>第三个顶级项目 </ol>
4.7. 输出计数器:counter() 和 counters() 函数
计数器本身没有可见效果,但它们的值可以与counter()和counters()函数一起使用,这些函数的使用值以字符串或图像的形式表示计数器值。它们的定义如下:
<counter> = <counter()> | <counters()> counter() = counter( <counter-name>, <counter-style>? ) counters() = counters( <counter-name>, <string>, <counter-style>? )
其中<counter-style>指定用于生成命名计数器的表示形式的计数器样式,正如生成计数器中定义的那样。
- counter()
- 表示元素的最内层计数器的值,该计数器在元素的CSS计数器集中使用<counter-name>指定的计数器样式,并且样式名为<counter-style>。
- counters()
- 表示元素的计数器在元素的CSS计数器集中命名的所有计数器的值,使用名为<counter-name>的计数器样式,并且样式名为计数器样式,按外层优先至内层最后的顺序排列,并通过指定的<string>连接。
在这两种情况下,如果<counter-style>参数被省略,则默认为decimal。
如果在使用counter()或counters()的元素上不存在命名为<counter-name>的计数器,则将首先以初始值为0对其进行实例化。
H1::before { content: counter(chno, upper-latin) ". " } /* 生成标题如 "A. A History of Discontent" */ H2::before { content: counter(section, upper-roman) " - " } /* 生成标题如 "II - The Discontent Part" */ BLOCKQUOTE::after { content: " [" counter(bq, decimal) "]" } /* 生成以 "... [3]" 结尾的块引用 */ DIV.note::before { content: counter(notecntr, disc) " " } /* 在每个div.note之前简单生成一个项目符号 */ P::before { content: counter(p, none) } /* 插入无内容 */
< ul > < li > 一个</ li > < li > 两个< ul > < li > 嵌套一个</ li > < li > 嵌套两个</ li > </ ul > </ li > < li > 三个</ li > </ ul > < style > li :: marker { content : '(' counters ( list-item , '.' ) ') ' ; } </ style >
上述文档应渲染如下:
(1) 一个 (2) 两个 (2.1) 嵌套一个 (2.2) 嵌套两个 (3) 三个
< h1 > 第一个H1</ h1 > ...< h2 > 第一个H2在H1中</ h2 > ...< h2 > 第二个H2在H1中</ h2 > ...< h3 > 第一个H3在H2中</ h3 > ...< h1 > 第二个H1</ h1 > ...< h2 > 第一个H2在H1中</ h2 > ...< style > body { counter-reset : h1 h2 h3 ; } h1 { counter-increment : h1 ; counter-reset : h2 h3 ; }h2 { counter-increment : h2 ; counter-reset : h3 ; } h3 { counter-increment : h3 ; } h1 :: before { content : counter( h1 , upper-alpha ) ' ' ; } h2 :: before { content : counter( h1 , upper-alpha ) '.' counter( h2 , decimal ) ' ' ; } h3 :: before { content : counter( h1 , upper-alpha ) '.' counter( h2 , decimal ) '.' counter( h3 , lower-roman ) ' ' ; } </ style >
上述文档应渲染如下:
A. 第一个H1 ... A.1 第一个H2在H1中 ... A.2 第二个H2在H1中 ... A.2.i 第一个H3在H2中 ... B. 第二个H1 ... B.1 第一个H2在H1中 ...
其他用例涉及具有不同变换的嵌套或兄弟元素。今天,您需要使用预处理器以合理的方式做到这一点,但计数器可以使其在“纯”CSS中很好地工作。
建议添加一个counter-value(<counter-name>)函数,该函数返回名为计数器的值作为整数,而不是返回字符串。
请参阅问题1026。
附录 A:HTML 的示例样式表
本节为信息性,而非规范性。[HTML] 渲染章节定义了适用于 HTML 列表的规范默认属性;此示例样式表旨在通过熟悉的标记约定来说明 CSS 特性。
关于如何在 CSS
中支持ol[reversed]
列表编号的讨论仍在进行中。请参见,例如问题
4181。
/* 设置列表项 */ li { display: list-item; /* 隐含 'counter-increment: list-item' */ } /* 设置 ol 和 ul,使其作用于 list-item 计数器 */ ol, ul { counter-reset: list-item; } /* 列表的默认样式类型 */ ol { list-style-type: decimal; } ul { list-style-type: toggle(disc, circle, square); } /* ol 和 ul 元素上的 type 属性 */ ul[type="disc"] { list-style-type: disc; } ul[type="circle"] { list-style-type: circle; } ul[type="square"] { list-style-type: square; } ol[type="1"] { list-style-type: decimal; } ol[type="a"] { list-style-type: lower-alpha; } ol[type="A"] { list-style-type: upper-alpha; } ol[type="i"] { list-style-type: lower-roman; } ol[type="I"] { list-style-type: upper-roman; } /* ol 元素上的 start 属性 */ ol[start] { counter-reset: list-item calc(attr(start integer, 1) - 1); } /* li 元素上的 value 属性 */ li[value] { counter-set: list-item attr(value integer, 1); } /* 盒模型规则 */ ol, ul { display: block; margin-block: 1em; marker-side: match-parent; padding-inline-start: 40px; } ol ol, ol ul, ul ul, ul ol { margin-block: 0; } li { text-align: match-parent; }
感谢
本规范得益于以下人员的贡献:Aharon Lanin、Arron Eicholz、Brad Kemper、David Baron、Emilio Cobos Álvarez、Mats Palmgren、Oriol Brufau、Simon Sapin、Xidorn Quan。
修改记录
本节记录了自上次发布以来的更改。
自 2020 年 7 月 9 日 WD 以来的更改
- 澄清了适用于 ::marker 盒子与 ::marker 盒子内容的属性。(问题 4568)
- 在 UA 默认样式表中为 text-transform: none。(问题 4206)
- 更改了计数器继承,从父元素中获取值,只有在新计数器的情况下才从兄弟元素获取。(问题 5477)
自 2019 年 8 月 17 日 WD 以来的更改
- 指定了 outside 列表标记为 块容器。(它们的 外部显示类型 仍未定义。)
- 从 [CSS-PSEUDO-4] 中获取适用于 ::marker 的属性列表,并添加动画、过渡和 white-space。
- 在 UA 默认样式表中为 white-space: pre。(问题 4448)然而,请注意,标记框的确切空格处理行为仍在研究中。
自 2019 年 4 月 25 日 WD 以来的更改
- 重新编写了§ 4 自动编号与计数器部分,以提高精确度、编辑清晰度和与 CSS2 的同步性。
自 2014 年 3 月 20 日 WD 以来的更改
- 一致使用 <custom-ident> 作为计数器名称。
- 删除了 position: marker(标记定位现在大多未定义,如 CSS2 中所示)。
- 完全重写了关于标记的章节,以使其更为紧凑、与当前期望一致,并进行编辑改进。
- 将 list-item 计数器定义移至其自身部分,添加示例并进行了一些澄清。
- 将 marker-side 的值重命名为匹配框/文本对齐的约定。
- 定义 counter-set 在 counter-increment 之后应用,而不是之前。(问题 3810)
- 建立了 list-style 序列化的规范顺序,以将 <'list-style-type'> 放在最后。(问题 2624)
与 CSS Level 2 的变化
如引言部分所述, 本模块与 CSS2.1 相比,有显著的变化。
- 引入了 ::marker 伪元素,以允许直接样式化列表标记。
- list-style-type 现在接受 <string> 以及扩展的 <counter-style> 值,来自 [css-counter-styles-3]。
- 引入了 list-item 预定义计数器标识符。
- 新增了 counter-set 属性。
- 允许使用 inline-level 列表项,如在 [CSS-DISPLAY-3] 中引入的。