内容
在某些情况下,作者可能希望用户代理渲染不来自文档树的内容。一个常见的例子是编号列表;作者并不想显式列出数字,而是希望用户代理自动生成它们。同样,作者可能希望用户代理在图形的说明之前插入“Figure”一词,或在第七章标题之前插入“Chapter 7”。尤其对于音频或盲文,用户代理应该能够插入这些字符串。
在 CSS 2.1 中,内容可以通过两种机制生成
作者使用 :before 和 :after 伪元素来指定生成内容的样式和位置。正如其名称所示,:before 和 :after 伪元素分别指示内容位于元素的文档树内容之前或之后。‘content’ 属性结合这些伪元素,指定要插入的内容。
例如,下面的规则在每个 class 属性值为 “note” 的 P 元素内容之前插入字符串 “Note: ”
p.note:before { content: "Note: " }
由元素生成的格式化对象(例如盒子)包括生成的内容。因此,例如,把上述样式表改为
p.note:before { content: "Note: " }
p.note { border: solid green }
将导致在整个段落周围渲染出实心绿色边框,包括最初的字符串。
:before 和 :after 伪元素会继承它们所附着的文档树中元素的所有可继承属性。
例如,下面的规则在每个 Q 元素之前插入开引号。引号的颜色将为红色,但字体将与 Q 元素其余部分的字体相同。
q:before {
content: open-quote;
color: red
}
在 :before 或 :after 伪元素的声明中,非继承属性采用其初始值。
因此,例如,由于 ‘display’ 属性的初始值为 ‘inline’,前例中的引号被插入为行内盒(即与元素的初始文本内容在同一行)。下面的例子显式将 ‘display’ 属性设为 ‘block’,从而使插入的文本成为块级元素。
body:after {
content: "The End";
display: block;
margin-top: 2em;
text-align: center;
}
:before 和 :after 伪元素与其他盒子的交互方式就像它们是真正的元素,插入在其关联元素内部一样。
例如,下面的文档片段和样式表
<p> Text </p> p:before { display: block; content: 'Some'; }
...将以完全相同的方式渲染为下面的文档片段和样式表
<p><span>Some</span> Text </p> span { display: block }
同样,下面的文档片段和样式表
<h2> Header </h2> h2:after { display: block; content: 'Thing'; }
...将以完全相同的方式渲染为下面的文档片段和样式表
<h2> Header <span>Thing</span></h2> h2 { display: block; }
span { display: block; }
注意。 本规范未完全定义 :before 和 :after 与被替换元素(如 HTML 中的 IMG)的交互方式。此内容将在未来的规范中更详细地定义。
| 值 | normal | none | [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit |
| 初始值 | normal |
| 应用于 | :before 与 :after 伪元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | all |
| 计算值 | 在普通元素上,总是计算为 ‘normal’。在 :before 和 :after 上,如果指定为 ‘normal’,则计算为 ‘none’。否则,对于 URI 值,返回绝对 URI;对于 attr() 值,返回结果字符串;对于其他关键字,按规定解释。 |
该属性与 :before 和 :after 伪元素配合使用,以在文档中生成内容。取值含义如下
‘display’ 属性控制内容是放置在块级盒还是行内盒中。
以下规则将在每个 H1 元素之前生成字符串 “Chapter: ”
H1:before {
content: "Chapter: ";
display: inline;
}
作者可以在生成的内容中通过在 'content' 属性后的字符串中写入 “\A” 转义序列来插入换行符。插入的换行仍受 'white-space' 属性的影响。有关 “\A” 转义序列的更多信息,请参见 “字符串” 和 “字符与转义”。
h1:before {
display: block;
text-align: center;
white-space: pre;
content: "chapter\A hoofdstuk\A chapitre"
}
生成的内容不会改变文档树。特别是,它不会反馈给文档语言处理器(例如,重新解析)。
在 CSS 2.1 中,作者可以以样式敏感且上下文相关的方式指定用户代理渲染引号的方式。‘quotes’ 属性为每个层次的嵌套引用指定一对引号。‘content’ 属性可访问这些引号,并在引用前后插入它们。
该属性为任意层次数的嵌套引用指定引号。取值含义如下
例如,应用以下样式表
/* Specify pairs of quotes for two levels in two languages */
q:lang(en) { quotes: '"' '"' "'" "'" }
q:lang(no) { quotes: "�" "�" '"' '"' }
/* Insert quotes before and after Q element content */
q:before { content: open-quote }
q:after { content: close-quote }
作用于下面的 HTML 片段
<HTML lang="en">
<HEAD>
<TITLE>Quotes</TITLE>
</HEAD>
<BODY>
<P><Q>Quote me!</Q>
</BODY>
</HTML>
将导致用户代理产生
"Quote me!"
而下面的 HTML 片段
<HTML lang="no">
<HEAD>
<TITLE>Quotes</TITLE>
</HEAD>
<BODY>
<P><Q>Trøndere gråter når <Q>Vinsjan på kaia</Q> blir deklamert.</Q>
</BODY>
</HTML>
将产生
�Trøndere gråter når "Vinsjan på kaia" blir deklamert.�
注意。 虽然前面示例中的引号在键盘上易于输入,但高质量排版需要使用不同的 ISO 10646 字符。下面的信息表列出了一些 ISO 10646 引号字符。
| 字符 | 大致渲染 | ISO 10646 代码(十六进制) | 描述 |
|---|---|---|---|
| " | " | 0022 | 引号 [ASCII 双引号] |
| ' | ' | 0027 | 撇号 [ASCII 单引号] |
| ‹ | < | 2039 | 单左尖角引号 |
| › | > | 203A | 单右尖角引号 |
| « | � | 00AB | 左双尖角引号(LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) |
| » | � | 00BB | 右双尖角引号(RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) |
| ‘ | ` | 2018 | 左单引号 [single high-6] |
| ’ | ' | 2019 | 右单引号 [single high-9] |
| “ | `` | 201C | 左双引号 [double high-6] |
| ” | '' | 201D | 右双引号 [double high-9] |
| „ | ,, | 201E | 双低位 9 引号 [double low-9] |
使用 'open-quote' 和 'close-quote' 值,'content' 属性会在文档的适当位置插入引号。每次出现 ‘open-quote’ 或 ‘close-quote’ 都会被 'quotes' 属性值中的相应字符串替换,依据嵌套深度。
‘open-quote’ 指一对引号的开头,‘close-quote’ 指其结尾。使用哪一对引号取决于引号的嵌套层级:即在当前出现之前,所有生成文本中 ‘open-quote’ 的出现次数减去 ‘close-quote’ 的出现次数。如果深度为 0,使用第一对;深度为 1,使用第二对,依此类推。如果深度大于可用的引号对数量,则重复最后一对。若 ‘close-quote’ 或 ‘no-close-quote’ 会导致深度为负,则视为错误并被忽略(在渲染时),深度保持为 0,且不渲染引号字符(虽然 ‘content’ 属性的其余部分仍被插入)。
注意。 引号深度与源文档的嵌套或格式结构无关。
某些排版风格要求在跨越多段的引用中,每段前都重复开引号,但仅在最后一段结束时放置闭引号。在 CSS 中,可通过插入“幻影”闭引号实现。关键字 'no-close-quote' 会递减引号层级,但不插入引号字符。
以下样式表在每个 BLOCKQUOTE 的段落前插入开引号,并在末尾插入一个闭引号
blockquote p:before { content: open-quote }
blockquote p:after { content: no-close-quote }
blockquote p.last:after { content: close-quote }
这依赖于最后一个段落被标记为 class “last”。
为了对称,还存在 'no-open-quote' 关键字,它不插入任何内容,但将引号层级递增一次。
CSS 2.1 中的自动编号由两个属性控制,'counter-increment' 和 'counter-reset'。这些属性定义的计数器与 'content' 属性的 counter() 和 counters() 函数一起使用。
| 值 | [ <identifier> <integer>? ]+ | none | inherit |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | all |
| 计算值 | 按指定值 |
| 值 | [ <identifier> <integer>? ]+ | none | inherit |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | all |
| 计算值 | 按指定值 |
'counter-increment' 属性接受一个或多个计数器名称(标识符),每个名称后可选跟一个整数。该整数指示每次出现该元素时计数器递增的量。默认递增值为 1。允许使用 0 或负整数。
'counter-reset' 属性同样包含一个或多个计数器名称列表,每个名称后可选跟一个整数。该整数指定每次出现该元素时计数器被设定的值。默认值为 0。
计数器名称不得使用关键字 ‘none’,‘inherit’ 或 ‘initial’。单独使用 ‘none’ 表示不重置或递增计数器。单独使用 ‘inherit’ 具有其常规含义(参见 6.2.1)。‘initial’ 保留供将来使用。
以下示例展示了如何使用 “Chapter 1”、 “1.1”、 “1.2” 等方式为章节与小节编号。
BODY {
counter-reset: chapter; /* Create a chapter counter scope */
}
H1:before {
content: "Chapter " counter(chapter) ". ";
counter-increment: chapter; /* Add 1 to chapter */
}
H1 {
counter-reset: section; /* Set section to 0 */
}
H2:before {
content: counter(chapter) "." counter(section) " ";
counter-increment: section;
}
如果一个元素在递增/重置计数器的同时也在其 :before 或 :after 伪元素的 'content' 属性中使用该计数器,则计数器在递增/重置之后才被使用。
如果同一元素既重置又递增计数器,则先重置后递增。
如果在 'counter-reset' 与 'counter-increment' 属性的值中多次指定同一计数器,则每次重置/递增按指定顺序处理。
以下示例将 ‘section’ 计数器重置为 0
H1 { counter-reset: section 2 section }
以下示例将 ‘chapter’ 计数器递增 3
H1 { counter-increment: chapter chapter 2 }
'counter-reset' 属性遵循层叠规则。因此,由于层叠,以下样式表
H1 { counter-reset: section -1 }
H1 { counter-reset: imagenum 99 }
只会重置 ‘imagenum’。若要同时重置两个计数器,需要一起指定它们。
H1 { counter-reset: section -1 imagenum 99 }
计数器是“自嵌套”的,这意味着在后代元素或伪元素中重置计数器会自动创建该计数器的新实例。这对于 HTML 中的列表等情况尤为重要,因为元素可以无限深度地相互嵌套。为每个层级定义唯一名称的计数器几乎不可能。
因此,下面的方式足以为嵌套列表项编号。其结果与在 LI 元素上设置 ‘display:list-item’ 和 ‘list-style: inside’ 十分类似
OL { counter-reset: item }
LI { display: block }
LI:before { content: counter(item) ". "; counter-increment: item }
作用域 对于计数器而言,从文档中第一个对该计数器设置了 'counter-reset' 的元素开始,包括该元素的后代以及它的后续兄弟元素及其后代。但不包括在后续兄弟元素或同一元素后续的 ‘counter-reset’ 所创建的同名计数器的作用域内的任何元素。
如果在元素或伪元素上的 'counter-increment' 或 'content' 引用了一个未在任何 'counter-reset' 的作用域内的计数器,实现应当表现得好像在该元素或伪元素上已经有一个将计数器重置为 0 的 'counter-reset'。
在上面的示例中,OL 会创建一个计数器,OL 的所有子元素都会引用该计数器。
如果我们用 item[n] 表示第 n 个 “item” 计数器的实例,用 “{” 和 “}” 表示作用域的开始和结束,则下面的 HTML 片段将使用所指示的计数器。(我们假设样式表如上例所示)。
<OL> <!-- {item[0]=0 -->
<LI>item</LI> <!-- item[0]++ (=1) -->
<LI>item <!-- item[0]++ (=2) -->
<OL> <!-- {item[1]=0 -->
<LI>item</LI> <!-- item[1]++ (=1) -->
<LI>item</LI> <!-- item[1]++ (=2) -->
<LI>item <!-- item[1]++ (=3) -->
<OL> <!-- {item[2]=0 -->
<LI>item</LI> <!-- item[2]++ (=1) -->
</OL> <!-- -->
<OL> <!-- }{item[2]=0 -->
<LI>item</LI> <!-- item[2]++ (=1) -->
</OL> <!-- -->
</LI> <!-- } -->
<LI>item</LI> <!-- item[1]++ (=4) -->
</OL> <!-- -->
</LI> <!-- } -->
<LI>item</LI> <!-- item[0]++ (=3) -->
<LI>item</LI> <!-- item[0]++ (=4) -->
</OL> <!-- -->
<OL> <!-- }{item[0]=0 -->
<LI>item</LI> <!-- item[0]++ (=1) -->
<LI>item</LI> <!-- item[0]++ (=2) -->
</OL> <!-- -->
另一个示例展示在非嵌套元素上使用计数器时作用域的工作方式,如下所示。这展示了上述用于为章节和节编号的样式规则如何应用于给定的标记。
<!--"chapter" counter|"section" counter -->
<body> <!-- {chapter=0 | -->
<h1>About CSS</h1> <!-- chapter++ (=1) | {section=0 -->
<h2>CSS 2</h2> <!-- | section++ (=1) -->
<h2>CSS 2.1</h2> <!-- | section++ (=2) -->
<h1>Style</h1> <!-- chapter++ (=2) |}{ section=0 -->
</body> <!-- | } -->
‘counters()’ 函数生成一个由所有在作用域内同名计数器的值组成的字符串,之间用给定的字符串分隔。
下面的样式表将嵌套列表项编号为 “1”、 “1.1”、 “1.1.1” 等。
OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }
默认情况下,计数器使用十进制数字格式化,但也可以使用 'list-style-type' 属性所支持的所有样式。语法为
counter(name)
表示默认样式,或
counter(name, <'list-style-type'>)
所有样式均被允许,包括 ‘disc’、‘circle’、‘square’ 和 ‘none’。
H1:before { content: counter(chno, upper-latin) ". " }
H2:before { content: counter(section, upper-roman) " - " }
BLOCKQUOTE:after { content: " [" counter(bq, lower-greek) "]" }
DIV.note:before { content: counter(notecntr, disc) " " }
P:before { content: counter(p, none) }
设置了 ‘display’ 为 ‘none’(即不显示)的元素无法递增或重置计数器。
例如,使用下面的样式表,类为 “secret” 的 H2 不会递增 ‘count2’。
H2.secret {counter-increment: count2; display: none}
未生成的伪元素同样无法递增或重置计数器。
例如,下面的代码不会递增 ‘heading’。
h1::before {
content: normal;
counter-increment: heading;
}
而 'visibility' 设置为 ‘hidden’ 的元素,会递增计数器。
CSS 2.1 提供了列表的基本视觉格式化。带有 ‘display: list-item’ 的元素会为其内容生成一个主块盒,并根据 ‘list-style-type’ 和 ‘list-style-image’ 的取值,可能还会生成一个标记盒,以视觉上指示该元素是列表项。
列表属性 描述了列表的基本视觉格式化:它们允许样式表指定标记类型(图像、字形或数字),以及标记相对于主盒的位置(在盒外或内容前的内部)。它们不允许作者为列表标记指定不同的样式(颜色、字体、对齐等)或相对于主盒调整其位置;这些可能从主盒派生。
背景属性 仅适用于主盒;“外部”标记盒是透明的。
| 值 | disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit |
| 初始值 | disc |
| 应用于 | 带有 ‘display:list-item’ 的元素 |
| 可继承 | 是 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
当 ‘list-style-image’ 为 ‘none’ 或指向的 URI 无法显示时,此属性指定列表项标记的外观。值 ‘none’ 表示没有标记;否则有三种标记类型:字形、数字系统和字母系统。
字形可通过 disc、circle 和 square 指定。其具体渲染方式取决于用户代理。
数字系统可通过以下方式指定:
字母系统可通过以下方式指定:
本规范未定义字母系统在字母表末尾的换算方式。例如,在 26 项列表后,‘lower-latin’ 的渲染未定义。因此,对于长列表,建议作者使用真实数字。
CSS 2.1 未定义列表编号的重置和递增方式。预计将在 CSS 列表模块 [CSS3LIST] 中定义。
例如,下面的 HTML 文档
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Lowercase latin numbering</TITLE>
<STYLE type="text/css">
ol { list-style-type: lower-roman }
</STYLE>
</HEAD>
<BODY>
<OL>
<LI> This is the first item.
<LI> This is the second item.
<LI> This is the third item.
</OL>
</BODY>
</HTML>
可能产生如下效果
i This is the first item. ii This is the second item. iii This is the third item.
列表标记的对齐方式(此处为右对齐)取决于用户代理。
| 值 | <uri> | none | inherit |
| 初始值 | none(无) |
| 应用于 | 带有 ‘display:list-item’ 的元素 |
| 可继承 | 是 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | absolute URI 或 ‘none’ |
该属性设置将用于列表项标记的图像。当图像可用时,它将替代由 'list-style-type' 标记设定的标记。
图像的尺寸按以下规则计算:
下面的示例将每个列表项开头的标记设为图像 “ellipse.png”。
ul { list-style-image: url("http://png.com/ellipse.png") }
| 值 | inside | outside | inherit |
| 初始值 | outside (外侧) |
| 应用于 | 带有 ‘display:list-item’ 的元素 |
| 可继承 | 是 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
该属性指定标记盒相对于主块盒的位置。取值含义如下
例如:
<HTML>
<HEAD>
<TITLE>Comparison of inside/outside position</TITLE>
<STYLE type="text/css">
ul { list-style: outside }
ul.compact { list-style: inside }
</STYLE>
</HEAD>
<BODY>
<UL>
<LI>first list item comes first
<LI>second list item comes second
</UL>
<UL class="compact">
<LI>first list item comes first
<LI>second list item comes second
</UL>
</BODY>
</HTML>
上述示例可以格式化为
在从右到左的文本中,标记会出现在盒子的右侧。
| 值 | [ <'list-style-type'> || <'list-style-position'> || <'list-style-image'> ] | inherit |
| 初始值 | 见各个属性 |
| 应用于 | 带有 ‘display:list-item’ 的元素 |
| 可继承 | 是 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 见各个属性 |
‘list-style’ 属性是为同时设置 'list-style-type'、'list-style-image' 和 'list-style-position' three properties 的简写表示法。
ul { list-style: upper-roman inside } /* Any "ul" element */
ul > li > ul { list-style: circle outside } /* Any "ul" child
of an "li" child
of a "ul" element */
尽管作者可以直接在列表项元素(例如 HTML 中的 “li”)上指定 'list-style' 信息,但应谨慎使用。以下规则看起来相似,但第一个声明了一个后代选择器,而第二个声明了(更具体的)子选择器。
ol.alpha li { list-style: lower-alpha } /* Any "li" descendant of an "ol" */
ol.alpha > li { list-style: lower-alpha } /* Any "li" child of an "ol" */
仅使用后代选择器的作者可能无法获得预期结果。考虑以下规则
<HTML>
<HEAD>
<TITLE>WARNING: Unexpected results due to cascade</TITLE>
<STYLE type="text/css">
ol.alpha li { list-style: lower-alpha }
ul li { list-style: disc }
</STYLE>
</HEAD>
<BODY>
<OL class="alpha">
<LI>level 1
<UL>
<LI>level 2
</UL>
</OL>
</BODY>
</HTML>
期望的渲染效果是一级列表项使用 'lower-alpha' 标记,二级列表项使用 'disc' 标记。然而,层叠顺序会导致第一个样式规则(包含特定类信息)覆盖第二个。下面的规则通过使用 子选择器 来解决该问题。
ol.alpha > li { list-style: lower-alpha }
ul li { list-style: disc }
另一种解决方案是仅在列表类型元素上指定 'list-style' 信息
ol.alpha { list-style: lower-alpha }
ul { list-style: disc }
继承会把 'list-style' 的值从 OL 和 UL 元素传递给 LI 元素。这是指定列表样式信息的推荐方式。
URI 值可以与任何其他值组合,例如:
ul { list-style: url("http://png.com/ellipse.png") disc }
在上述示例中,当图像不可用时将使用 ‘disc’。
在 'list-style' 属性中使用 ‘none’ 值时,会将 'list-style-type' 和 'list-style-image' 中未另行指定为 ‘none’ 的属性设为 ‘none’。然而,如果两者均已指定,则此声明为错误(因此被忽略)。
例如,在 'list-style' 属性中使用 ‘none’ 值会将 'list-style-type' 和 'list-style-image' 均设为 ‘none’
ul { list-style: none }
结果是不会显示任何列表项标记。