内容
某些情况下,编写者可能想让用户代理渲染来自文档树外的内容。一个熟悉的此类例子是编号列表,编写者不想显式地列出编号,他/她想让用户代理自动生成它们。类似的,编写者可能想让用户代理在一幅图的标题前插入“图”这个字,或者在第七章的标题前插入“第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)的相互影响。这会在将来的规范中详细定义
Value: | normal | none | [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit |
Initial: | normal |
Applies to: | :before和:after伪元素 |
Inherited: | no |
Percentages: | N/A |
Media: | all |
Computed value: | 对于元素,计算值为'normal'。对于:before和:after,如果指定值为'normal',计算值就是'none'。否则,对于URI值,(计算值)就是绝对URI;对于attr()值,就是产生的字符串;对于其它关键字,就与指定值相同 |
该属性配合:before和:after伪元素来在文档中生成内容。值含义如下:
'display'属性控制内容放在一个块还是行内盒里
如下规则会在每个H1元素前生成字符串"Chapter: ":
H1:before { content: "Chapter: "; display: inline; }
编写者可以通过在'content'属性后面的字符串中写上"\A"转义序列,来在生成的内容中包含换行(newlines)。插入的这个行结束符也受'white-space'属性约束。关于"\A"转义序列的更多信息见“字符串”与“字符和大小写”
h1:before { display: block; text-align: center; white-space: pre; content: "chapter\A hoofdstuk\A chapitre" }
生成的内容不会改变文档树。特别的,它不会反馈给文档语言处理器(例如,用于重新解析)
CSS 2.1中,编写者可以指定用户代理应该怎样渲染引号,以风格敏感的(style-sensitive)还是依赖上下文的(context-dependent)方式。'quotes'属性为每层内嵌引用指定了引号对儿。'content'属性允许访问那些引号,并且会让他们插入在一个引用(quotation)之前和之后
该属性为所有内嵌引用指定了引号。值含义如下:
例如,应用下列样式表:
/* 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.»
注意 尽管前一个示例中通过'quotes'指定的引号都很方便地位于计算机键盘上,但高质量排版将会需要不同的ISO 10646字符。下面信息性的表格列出了一些ISO 10646引号字符:
Character | Approximate rendering | ISO 10646 code (hex) | Description |
---|---|---|---|
" | " | 0022 | QUOTATION MARK [the ASCII double quotation mark] |
' | ' | 0027 | APOSTROPHE [the ASCII single quotation mark] |
‹ | < | 2039 | SINGLE LEFT-POINTING ANGLE QUOTATION MARK |
› | > | 203A | SINGLE RIGHT-POINTING ANGLE QUOTATION MARK |
« | « | 00AB | LEFT-POINTING DOUBLE ANGLE QUOTATION MARK |
» | » | 00BB | RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK |
‘ | ` | 2018 | LEFT SINGLE QUOTATION MARK [single high-6] |
’ | ' | 2019 | RIGHT SINGLE QUOTATION MARK [single high-9] |
“ | `` | 201C | LEFT DOUBLE QUOTATION MARK [double high-6] |
” | '' | 201D | RIGHT DOUBLE QUOTATION MARK [double high-9] |
„ | ,, | 201E | DOUBLE LOW-9 QUOTATION MARK [double low-9] |
可以用值为'open-quote'和'close-quote'的'content'属性在文档中合适的地方插入引号。出现的每个'open-quote'或'close-quote'会被替换为'quotes'值中的某个字符串,根据嵌套的深度来定
'Open-quote'表示一对引号中的第一个,'close-quote'表示第二个。使用哪一对引号取决于引用的嵌套层级:'open-quote'在当前位置之前的所有生成文本中的出现次数,减去'close-quote'的出现次数。如果深度为0,就用第一对,如果深度为1,就用第2对,等等。如果深度大于(引号)对数,就重复最后一对。一个会让深度变为负数的'close-quote'或者'no-close-quote'属于错误情况,会被忽略掉(在渲染时):深度为0且不渲染引号(尽管仍然会插入'content'属性值的其余部分)
注意 引用深度独立于源文档或者格式化结构的嵌套
一些排版样式需要让左引号在横跨多段的引用中的每个段落前重复,但只在最后一段的结尾处有一个右引号。CSS中,这可以通过插入“虚拟(phantom)”右引号来实现。关键字'no-close-quote'能减少引用层级,但不会插入引号
下列样式表会给BLOCKQUOTE中的每个段落添上一个左引号,并在末尾插入一个右引号:
blockquote p:before { content: open-quote } blockquote p:after { content: no-close-quote } blockquote p.last:after { content: close-quote }
这需要给最后一段标记一个"last"类
对称的,也有一个'no-open-quote'关键字,不插入任何东西,但会让引用深度加1
自动编号在CSS 2.1中是通过两个属性控制的,'counter-increment'和'counter-reset'。通过这些属性定义的计数器用于'content'属性的counter()和counters()函数
Value: | [ <identifier> <integer>? ]+ | none | inherit |
Initial: | none |
Applies to: | 所有元素 |
Inherited: | no |
Percentages: | N/A |
Media: | all |
Computed value: | 与指定值相同 |
Value: | [ <identifier> <integer>? ]+ | none | inherit |
Initial: | none |
Applies to: | 所有元素 |
Inherited: | no |
Percentages: | N/A |
Media: | all |
Computed value: | 与指定值相同 |
'counter-increment'属性接受一个或多个计数器名(标识符),每个后面都可以跟一个可选的整数。这个整数表示每次出现该元素时计数器递增几。默认增量是1,可以接受0和负数
'counter-reset'属性也含有一列一个或多个计数器,每个后面可以跟一个可选的整数。该整数给定了每次出现该元素时给计数器设置的值,默认为0
关键字'none','inherit'和'initial'不能用作计数器名。值为'none'表示不需要重置或者递增计数器。'Inherit'表示它('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 }
计数器是“自嵌套的(self-nesting)”,如果重置一个位于后代元素或者伪元素中的计数器,会自动创建一个新的计数器实例。这对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'作用域的计数器,实现应该表现得就像已经通过该元素或伪元素上的'counter-reset'把该计数器重置为0了一样
上例中,OL将会创建一个计数器,并且OL的所有子级将引用该计数器
如果我们用item[n]表示"item"计数器的第n个实例,用"{"和"}"表示一个作用域的开始和结束,那么下列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'的元素会为该元素的内容生成一个主块盒(principal block box),还可能用一个标记盒(marker box)作为可视化指示,表明该元素是个列表项,这取决于'list-style-type'和'list-style-image'的值
list属性描述了列表的基础视觉格式化:它们允许样式表指定标记类型(图片,字形或者数字),及标记相对主盒的位置(在它内部或者外部,在内容之前)。但它们不允许编写者为列表标记指定确切的样式(颜色,字体,对齐方式等等)或者调整它相对于主盒的位置,这些都会从主盒继承得到
background属性只适用于主盒,“外部的”标记盒是透明的
Value: | 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 |
Initial: | disc |
Applies to: | 具有'display: list-item'的元素 |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | 与指定值相同 |
该属性指定了列表项标记的外观。如果'list-style-image'置为'none'或者如果URI指向的图片无法显示的话,'none'值不指定标记,否则有三种标记类型:字形,编号系统(numbering systems)和字母系统(alphabetic systems)
字形通过disc,circle和square来指定。其确切的呈现效果取决于用户代理
编号系统通过下列(值)来指定:
字母系统通过下列(值)来指定:
本规范没有定义字母系统在字母表结束处怎样处理(wrap),例如,在26个列表项之后,'lower-latin'的渲染是未定义的。因此,对于长列表,我们建议编写者指定真正的数字
CSS 2.1没有定义列表编号怎样重置和递增。预期在CSS List Module [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.
列表标记对齐方式(这里是右对齐)取决于用户代理
Value: | <uri> | none | inherit |
Initial: | none |
Applies to: | 具有'display: list-item'的元素 |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | 绝对URI或者'none' |
该属性设置了将用作列表项标记的图片。当图片可用时,它将代替用'list-style-type'设置的标记
图片的尺寸根据下列规则计算:
下例把每个列表项的开始处的标记设置为图片"ellipse.png"
ul { list-style-image: url("http://png.com/ellipse.png") }
Value: | inside | outside | inherit |
Initial: | outside |
Applies to: | 具有'display: list-item'的元素 |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | 与指定值相同 |
该属性指定了标记盒(marker box)相对于主块盒的位置(principal block box)。值含义如下:
例如:
<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>
上例可能会被格式化为:
在从右向左的文本中,标记将位于该盒的右边
Value: | [ <'list-style-type'> || <'list-style-position'> || <'list-style-image'> ] | inherit |
Initial: | 见单独的各个属性 |
Applies to: | 具有'display: list-item'的元素 |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | 见单独的各个属性 |
'list-style'属性是在样式表中一次性设置'list-style-type','list-style-image'和'list-style-position'三个属性的简写表示法
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>
想要的渲染效果是让1级列表项带有'lower-alpha'标签,2级列表项带有'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'。然而,如果(在简写属性中)同时指定了两者,声明将出错(因而被忽略)(译注:例如list-style: none disc url(bullet.png);
,见5 The list-style shorthand property EXAMPLE 6)
例如,值为'none'的'list-style'属性会把'list-style-type'和'list-style-image'设置为'none':
ul { list-style: none }
结果是不会显示列表项标记