纯CSS实现目录自动编号

纵观一篇word文档,一般都是通过章节来组织整个正文的内容,而构成正文的基本元素包括段落、列表、表格、超链接及嵌入式对象(如图片、视频、音频、文档)等。

通过这些基本元素的排列、组合、嵌套,便构成了纷繁复杂、有条不紊的word文档。本节通过构建这些基本元素,来剖析一篇 word 文档的构建过程。

章节

在 word 文档中,都是通过各级标题来组织章节。对应到HTML中,使用标题元素 h1~h6 来定义文档的各级标题,标题元素采用层次结构,h1表示一级标题,h2表示二级标题,以此类推。如:

 
  1. <h1>CSS的选择器</h1>
  2.    <h2>基本选择器</h2>
  3.        <h3>元素选择器</h3>
  4.        <h3>类选择器</h3>
  5.        <h3>id选择器</h3>
  6.        <h3>群组选择器</h3>
  7.    <h2>关系选择器</h2>
  8.        <h3>后代选择器</h3>
  9.        <h3>子选择器</h3>
  10.        <h3>相邻同胞选择器</h3>
  11.        <h3>同胞选择器</h3>

默认情况下,浏览器会把标题渲染为加粗字体,h1 的字体最大,h6 的字体最小,表示内容的重要性逐级降低。并且,为了防止标题和内容过分拥挤,浏览器通常会在标题的上下,各留出一定的间隙。

浏览器的默认效果,不可能满足所有人的要求。所以,CSS设计师通常会根据需要,来重置标题的样式,如外边距、内边距、字体样式等,以满足自己的要求。如:

 
  1. h1, h2, h3 {
  2.    margin: 0;
  3.    padding: 0;
  4.    font-weight: normal;
  5. }

标题为块级元素,可以设置边距、边框、背景、字体、文本等相关样式。这些都非常简单,并且在前面已经有过详细介绍,这里就不再赘述。

众所周知,word 有一项非常人性化的功能,就是用户可以随意增删任何一级标题,而不必人工重新修改编号,这些都由 word 自动完成。而我们制作的网页版 word 能否具备此功能呢?接下来,带领大家一起探索一下。

可以想象,标题的编号,其实就是在标题文本的前面,插入一个可以自动计数的计数器。

在CSS中,使用伪元素选择器 E::before,可以在元素前面插入内容,而插入的内容由content 属性生成。如果把 content 属性的值设置为某个计数器,即可把计数器的值插入到元素的前面。格式如下:

 
  1. E::before {
  2.     content: counter(计数器名称);
  3. }

借助这个功能,就可以实现标题的自动编号功能。其实,属性值 counter 只是对计数器的引用而已,计数器还要在其它待计数的选择器中定义。CSS中,使用 counter-increment属性来定义计数器,其名称可以是任意合法的字符串。

 
  1. h1 {
  2.     counter-increment: counter_h1;
  3. }
  4. h1::before {
  5.     content: counter(counter_h1);
  6. }

上述代码,在选择器 h1 中定义了名称为 counter_h1 的计数器,并在 h1::before 选择器中引用了该计数器,即可把计数器的值插入到 h1 的前面。可以使用同样的方法,来定义 h2、h3 标题前插入的内容。运行结果如图 11‑7 所示:

各级标题连续编号图11-7 各级标题连续编号

从上图可以看出,所有的 h3 标题为统一编号(见红线标注),应该是每个 h2 下的 h3各自独立编号。

如果要将 h2 下的 h3 重新编号,还需要在 h2 中,使用 counter-reset 属性,来重置指定的计数器。这里需要重置的是 h2 中的 counter_h3 计数器。

 
  1. h2 {
  2.      counter-increment: counter_h2;
  3.      counter-reset: counter_h3;
  4. }

经过上述修改后,运行结果如图 11‑8 所示:

重置自动编号图11-8 重置自动编号

从上图可以看出,h2 下的h3 确实独立编号了。但是,h1 和 h2 都是以 1、2、3 的形式进行编号,我们希望 h1 是“1.”、“2.”的形式,而h2是“1.1”、“2.1”的形式。

先看一级标题,其实就是希望在编号后添加一个 “.”。要在 content 的内容中添加固定的文本比较简单,只需把文本的内容添加到 content 属性值的指定位置即可。

 
  1. h1::before {
  2.     content: counter(counter_h1)".";
  3. }
  4. h2::before {
  5.     content: counter(counter_h1)"."counter(counter_h2);
  6. }

再看二级标题,二级标题要引用一级标题的序号。沿用以上的思路,直接把一级标题的计数器和 “.” 拿来,添加到 h1::before 的 content 属性值中即可。对三级标题,也采用同样的思路。

 
  1. h3 {
  2.     counter-increment: counter_h3;
  3. }
  4. h3::before {
  5.     content: counter(counter_h1)"."counter(counter_h2)"."counter(counter_h3);
  6. }

经过上述修改后,运行结果如图 11‑9 所示:

添加章节编号前缀图11-9 添加章节编号前缀

从上图可以看出,所有的编号都已经符合要求,但是标题文本和编号之间距离太小,过于拥挤。可以在插入内容的右侧,设置一定的内边距,使标题文本和编号之间保持一定距离。

 
  1. h1::before, h2::before, h3::before {
  2.      padding-right: 1em;
  3. }

同理,为了有效区分各级标题,也可以通过左外边距为不同标题设置不同的缩进,让各级标题层次分明。

 
  1. h1 {
  2.     margin-left: 1em;
  3. }
  4. h2 {
  5.     margin-left: 2em;
  6. }
  7. h3 {
  8.     margin-left: 3em;
  9. }

至此,标题的自动编号功能就完全实现了。运行结果如图 11‑10 所示:

章节自动编号图11-10 章节自动编号

有了自动编号,就可以随意增删任何一级标题,再也不用担心编号发生混乱,也体现了CSS的强大。

在定义自动编号时,默认的编号类型是数字。当然,除数字外,也可以使用字母、罗马数字等,只需在 counter 中指定编号种类即可,编号种类可以是 list-style-type 属性能支持的任何值。如:

 
  1. content: counter(counter_h1, lower-roman);

另外,counter-increment 属性默认是从 1 开始递增的。但是,可以提供第二个参数,让它从指定值开始递增。如:

 
  1. counter-increment: counter_h1, 10;

其实,在CSS1中,就有了伪元素选择器,而 E:before 选择器是CSS2才引入的。到了CSS3,伪元素选择器的语法发生了改变,E和 before 之间的冒号,由一个变成了两个。但是,现代浏览器仍然支持老的语法,你仍然可以使用 E:before。

关于作者

歪脖先生,十五年以上软件开发经验,酷爱Web开发,精通 HTML、CSS、JavaScript、jQuery、JSON、Python、Less、Bootstrap等,著有《HTML宝典》、《揭秘CSS》、《Less简明教程》、《JSON教程》、《Bootstrap2用户指南》、《Bootstrap3实用教程》,并全部在 GitHub 上开源。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值