CSS2学习笔记18

列表与生成内容

系列文章

列表

列表标志

可以修改用于列表项的标志内容:

list-style-type
值:
除了 inherit 外的其余值见下
初始值:
disc
应用于:
list-item 元素
继承性:
计算值:
根据指定确定

可以使用的值有:

该属性以及所有与列表相关的属性只能应用于 list-item 元素。

尽管有序列表与无序列表的标志可以混用,但应该注意浏览器可能的禁止。


还可以利用图像自定义列表项标志:

list-style-image
值:
URL | none | inherit
初始值:
none
应用于:
list-item 元素
继承性:
计算值:
对于 URL ,为绝对URL;否则为 none

以下是一个使用自定义图像的列表示意:

<ul style="list-style-image: url('list-item.png'); list-style: square;">
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>

通常提供一个后备的 list-style-type 用于防止图片未加载。

由于列表的标志可以继承,因此通常需要注意防止嵌套列表的标志被覆盖。

列表标志位置

标志可以防止列表项之内或之外:

list-style-position
值:
inside | outside | inherit
初始值:
outside
应用于:
list-item 元素
继承性:
计算值:
根据指定确定

下图比较了这两者的差异:

图片来源:tutorialbrain.com

为了简单起见,可以将以上3个属性合并:

list-style-position
值:
( list-style-type || list-style-image || list-style-position ) | inherit
初始值:
相对于各个属性
应用于:
list-item 元素
继承性:
计算值:
见单个属性

列表布局

列表项的表现类似块框。

如果标志放在列表项内容外,它们不会影响任何元素的布局,仅随着内容左边界的移动而移动。

列表元素本身也是一个块框,其中包含所有后代元素,以及列表标志。

为了容纳列表标志,列表项通常会有一些缩进。

生成内容

生成内容(generated content)指由浏览器创建的内容,而不是由标志或内容来表示。

列表标志就是生成内容。

插入生成内容

可以使用 :before:after 伪元素向文档中插入生成内容。

生成内容会放在元素框的内部。除了列表标志,无法把生成内容放在元素框之外。

CSS明确禁止浮动或定位 :before:after 内容,还禁止使用列表样式属性以及表属性。

需要使用以下属性来描述生成的内容:

content
值:
normal | ( STRING | URL | COUNTER | attr(IDENTIFIER) ) | open-quote | close-quote | no-open-quote | no-close-quote )+ | inherit
初始值:
normal
应用于:
:before:after 伪元素
继承性:
计算值:
对于 URL ,为绝对URL;对于属性引用,则为结果串;否则,根据指定确定

串值会根据引号内的内容原样显示,不处理其中的任何标记与字符实体,转义符除外。

URL值可以在适当的位置插入外部资源(图像、媒体等)。如果用户代理无法识别,则不显示任何东西。

可以取元素的属性值作为插入内容:

这张图很好地解释了插入属性作为内容。图片来源:Speaker Deck

例如,在链接后插入具体地址可能很有用:

a[href]:after {
     content: " [" attr(href) "] ";
}

生成内容很难处理引号。CSS使用以下属性来管理引号及其嵌套行为:

quotes
值:
( STRING STRING )+ | none | inherit
初始值:
取决于具体的用户代理
应用于:
所有元素
继承性:
计算值:
根据指定确定

除了关键字外,唯一合法的值是一对或多对串。在一对串中,前一个串定义了开始引号(open-quote),后一个串定义了结束引号(close-quote)。

串本身是引号时,也可以用引号将其包围。双引号可以用单引号包围,单引号也可以用双引号包围。

在多对串中,第二对及其以后的串用于设置嵌套元素的引号。
如果引号的嵌套层次大于已定义的引号对数,最后一对引号将重用于更深层次的嵌套。

利用生成引号可以实现一种排版效果:多段引用文本忽略的除最后的每段结束引号。
这时,前几段的实现为:

blockquote { quotes: '"' '"' "'" "'"; }
blockquote p:before { content: open-quote; }
blockquote p:after { content: no-close-quote; }

no-close-quote 用于结束引用嵌套,这样每一段都从相同的嵌套层次开始,因此不能省略。

计数器

有序列表中的列表项就是计数器。

首先可以重置计数器的值:

counter-reset
值:
( IDENTIFIER INTEGER ? )+ | none | inherit
初始值:
取决于具体的用户代理
应用于:
所有元素
继承性:
计算值:
根据指定确定

计数器标识符可以是任意合法的标签。如果没有指定整数,计数器默认重置为0。
指定的重置整数可以为负数。不过有些值可能无法正常显示。

还需要一个属性来指示元素将计数器递增:

counter-increment
值:
( IDENTIFIER INTEGER ? )+ | none | inherit
初始值:
取决于具体的用户代理
应用于:
所有元素
继承性:
计算值:
根据指定确定

它与 counter-reset 属性的区别在于,如果缺少整数,那么默认值是1。


要使用计数器,还应该结合使用 content 属性和一个与计数器相关的值。
以下是一个计数器使用示例:

div.ordered-zero { counter-reset: zero-start -1; }
div.ordered-zero div:before { counter-increment: zero-start;
    content: counter(zero-start) ') '; margin: 0.25em; }
显示效果示例

计数器由同一个元素递增和使用时,递增发生在计数器显示之前。
如果计数器在同一个元素中重置和显示,重置也在计数器显示之前发生。

经常利用以下样式:

h2:before, h3:before {
    content: counter(chapter) "." counter(section) "." counter(subsection) ". ";
}
h1:before { counter-increment: chapter; content: counter(chapter) ". "; }
h1 { counter-reset: section subsection;
    counter-increment: chapter; }
body { counter-reset: chapter -1; }

来为嵌套标题添加层级序号。

可以使用 counter(name, upper-alpha) 等为计数器指定不一样的样式。

displaynone 的元素并不会递增计数器,但是 visibilityhidden 的元素却会递增计数器。


为了对多层嵌套创建计数器,往往要写很长的规则。

CSS2.x描述了计数器的作用域(scope)概念。每层嵌套都会为给定计数器创建一个新的作用域。

每层嵌套都为计数器创建了一个新实例,因此它们的计数总是从头开始。

可以使用 counters() 使每层嵌套都创建一个新计数器追加到老计数器上。
例如,以下规则:

ol { counter-reset: nested-ordered; list-style-type: none; }
ol li:before { counter-increment: nested-ordered;
    content: counters(nested-ordered, ".") ": "}

可以实现类似这样的效果:

图片来源:smashingmagazine.com

基本来说,值 counters(nested-ordered, ".") 会显示各作用域的 nested-ordered 计数器,并追加一个点号,然后把对应一个给定元素的所有作用域计数器串起来。
这样多层嵌套列表项的前缀就会显示多个列表作用域的 nested-ordered 值。