原文链接:
Using HTML sections and outlines - Mozilla Developer Network
每集HTML5+CSS3网页布局教程-2大纲算法
HTML5标准带来了几个带有标准语义的新元素来描述Web文档结构。本文会介绍这些元素,并且讨论如何用这些元素定义令人满意的文档大纲。
HTML4时代的文档结构
文档的结构(或者可以说在body标签之间的结构)是展示和表现web页面的基础。HTML4使用了区块(sections)和子区块(sub-sections)的概念来描述文档的结构。使用div元素来定义一个区块,并且使用标题元素(h1-h6)来定义这个区块的标题。它们之间的关系决定了web文档的结构和大纲。
下面的这些代码:
Forest elephants
In this section, we discuss the lesser known forest elephants.
...this section continues...
Habitat
Forest elephants do not live in trees but among them.
...this subsection continues...
可以提炼出如下的大纲:
- Forest elephants
1.1 Habitat
定义一个大纲中的节点不一定非要使用div元素,其实,只要一个标题元素(h1-h6)就已经足够用来暗示一个节点了,所以这些标签:
Forest elephants
In this section, we discuss the lesser known forest elephants.
...this section continues...
Habitat
Forest elephants do not live in trees but among them.
...this subsection continues...
Diet
Mongolian gerbils
提炼出了如下的大纲:
- Forest elephants
1.1 Habitat
1.2 Diet - Mongolian gerbils
(译注:这段代码没有使用任何div标签,大纲是根据标题元素——例中为h1和h2——来提炼的)
HTML5解决的问题
在HTML4中,文档结构的定义和大纲的算法非常简陋,这带来了不少的问题:
【问题1】用div元素来定义具有语义的区块的话,没有特定的class就没法自动生成大纲(“这个div是大纲的一部分,用来定义区块或者子区块的?”还是“它仅仅就是个div,为了方便使用CSS用来做样式的?”),换句话说,HTML4在“什么是区块、区块的范围怎么定义”这些问题上很不明确。页面是否能自动生成大纲非常重要,因为大多数屏幕阅读器(为有视力障碍人士提供的辅助阅读技术)就是根据文档大纲来规整它们将要展示给用户的信息。而在HTML5中,大纲算法不再必须使用div元素,取代div的是一个新的元素——section.
【问题2】多文档的融合是个难题:引入一个从别处采集来的子文档很可能会改变标题元素的等级,而HTML4正事根据这些标题元素的等级来提炼大纲的。HTML5引入了一系列全新的定义区块的元素(article, section, nav和aside),这些元素有这样的特性:不管它内部的标题元素(h1-h6)是什么级别,它总是离它最近的祖先区块的子节点。
译者例:
h3标题
h2标题
从其他文档引入的div区块
上述代码提炼出的大纲如下:
1.h3标题
1.1.h1标题
2.h2标题
可以看到,h1标题竟然成为了h3标题的子节点,这就是section元素的功劳了。因为不管它内部的标题元素是老大(h1)还是老六(h6),它都乖乖的成为离他最近的祖先节点(body)的子节点。再看div,虽然理论上应该也是body的子节点,但由于h2的级别高于h3(h3是body的标题),所以在大纲中竟和body变成了同级节点。
【问题3】在HTML4中,每个节点都是大纲的一部分。但web文档有时候并不是线性的。web文档有时可能会包含特殊的区块来承载信息,但这些信息并不属于主文档的一部分,比如广告和注释。HTML5引入了aside元素,该元素不会作为大纲的节点而成为大纲的一部分。
【问题4】同样的,在HTML4中,由于每个节点都是大纲的一部分,所以也没有适合的区块来承载logo、菜单、目录、版权信息和法律条款等这些信息,因为这些信息和web页面的内容无关,而是和web站点有关。为了解决该问题,HTML5同样引入了三个新元素:①用来承载链接(例如导航菜单和目录)的nav元素②用来承载web站点相关信息的header元素③用来承载web站点相关信息的footer元素。请注意header和footer和section不同,它们不会在大纲中出现,只负责语义性的描述一个区块(译注:有点类似div,但具有语义)。
总而言之,HTML5带来了更准确的区块和标题功能,这使得文档的可控性更强,而且更容易被浏览器使用,从而更好地提高用户体验。
HTML5的大纲算法
让我们来看看大纲算法是如何提炼区块和标题的。
body元素中所有元素都是节点。除了body元素定义的主节点,定义节点可以分为“显性定义的节点”和“隐性定义的节点”两种(以下下简称为“显性节点”和“隐性节点”)。
1.显性定义节点
显性节点使用、
这段代码中section定义了一个顶级区块,顶级区块中定义了三个子区块(两个section和一个aside)。这段代码可以提炼出如下的大纲:
- Forest elephants
1.1 Introduction
1.2 Habitat
1.3 Untitled Section
(译注:还记得吗?aside定义的节点也能出现在大纲中,但上例中并没有为aside定义标题,所以在大纲中出现了untitled section的字样)
2.定义标题
HTML的布局元素用来定义文档的结构,HTML的标题元素则用来给这些结构和这些结构所提炼的大纲赋予意义。
规则很简单:当前区块的第一个标题元素就是这个区块在大纲中节点的标题。
标题元素根据它元素名字里的数字来划分等级,其中h1等级最高,h6等级最低。标题元素等级只有在同一个区块中才有意义;决定大纲的是文档的区块结构,而不是标题元素的等级。举例来说,参考如下代码:
这些代码提炼出如下大纲:
- Forest elephants
1.1 Habitat - Mongolian gerbils
(译注:之所以h3元素和h1元素同级,是因为h3所属的区块和h1所属的区块同级,这就说明了决定大纲的是区块结构,而不是标题元素的等级)
请注意标题元素的等级是不重要的(上例中h1是第一个顶级的区块的标题,h2是子区块的标题,h3是第二个顶级区块的标题)。任何等级的标题都可以用在显性区块里,但并不推荐这样做。
3.隐性定义节点
在HTML5中,并不是只能用这些区块定义元素来定义大纲,考虑到兼容统治了web很长时间的HTML4,HTML5制订了不使用区块定义元素而使用标题元素来定义的节点方法,并称之为隐性定义节点。
在一个显性定义的节点中,第一个标题元素是该显性节点的标题,从第二个标题元素开始(包括第二个标题元素),之后的标题元素会定义新的节点,这些新的节点就是隐性定义的节点(因为并没有用到显性定义节点的元素)。
隐性节点有可能作为同级节点或子节点存在,这取决于定义它的标题级别。
如果定义它的标题级别低于之前的标题级别,那么它作为子节点存在。看看代码:
提炼出下面的大纲:
- Forest elephants
1.1 Habitat (通过h3元素隐性定义)
如果定义它的标题级别和之前的标题级别相同,它将关闭之前的节点并隐性定义一个同级别的节点:
提炼出下面的大纲:
- Forest elephants
- Mongolian gerbils (通过h1元素隐性定义,同时关闭之前的区块)
如果定义它的标题级别高于之前的标题级别,它将关闭之前的节点并隐性定义一个同级别的节点:
Mammals
Whales
In this section, we discuss the swimming whales.
...this section continues...
提炼出下面的大纲:
- Mammals
1.1 Whales (通过h2元素隐性定义)
1.2 Forest elephants (通过section元素显性定义)
1.3 Mongolian gerbils (通过h3元素隐性定义,同时关闭之前的节点)
1.4 Reptiles (通过h2元素隐性定义,同时关闭之前的节点)
这种大纲并不是稍微瞥一眼就能快速通过标题元素读懂的大纲。为了让你的大纲和HTML(对于人的)可读性更强,建议使用显性标签来定义或关闭节点,并且建议在区块嵌套时,标题元素的级别符合自然习惯。但是,HTML5手册并不强制要求这么做。如果你发现浏览器没有按照你的预期渲染大纲,检查看看是不是有一些节点被标题元素隐性声明的节点关闭了。
译者例 - 稍微复杂的大纲:
这里写图片描述
提炼出下面的大纲:
1.文档标题
1.h3标题
1.h5标题
2.h4标题
1.h5标题
2.h3标题
3.h1标题
1.h2标题
1.h3标题
2.h2标题
分析:
这里写图片描述
3.根节点
在HTML中,一个有自己的大纲系统,但是,这些元素对于它们的祖先的大纲没有任何影响。Body元素是文档的逻辑根节点,也有一些元素引入外部的内容,比如blockquote, details, fieldset, figure和td.
举例来说:
上面的代码提炼出如下的大纲:
- Forest elephants
1.1 Introduction
1.2 Habitat
在section中的blockquote元素不显示在主大纲中,因为它是一个作为外部引用的、拥有独立内部大纲的根节点。(译注:事实上,所有的根节点元素都不会显示在主大纲中)
4.不属于主大纲的区块
HTML5中引入的两个新元素允许开发者定义一个区块,但这个区块不会在大纲中创建节点:
HTML5的aside元素定义一个区块,这个区块属于文档的主元素,但不属于主文档流(比如注释或广告区域)。它有独自的大纲,但不属于主大纲。
HTML5的nav元素定义一个用于承载导航链接的区块。一个文档中可以有好几个nav元素,比如一个用来存放页面内的链接(像是文章目录),一个用来存放站点的导航链接。这些链接并不属于主文档流和主大纲,而且一般不会被屏幕阅读器或其他辅助设备优先渲染。
5.头元素和尾元素
HTML5也引入了两个新的元素用来标记头部和尾部:
HTML5的header元素定义页面的头部——通常包含logo、站点名称,也可能包含一个水平导航菜单。当然header也可以作为区块的头部,用来承载区块的标题、作者等。像article, section, aside和nav元素都可以有它自己的header.不过,你也不一定非要在每个页面或区块的都不放置这样一个元素。
HTML5的footer元素定义页面的尾部——通常包含版权信息、法律声明,有时候还包含一些链接。当然footer也可以作为区块的尾部,可能用来承载区块里面内容的出版时间、版权信息等等。像atricle, section, aside和nav元素都可以有自己的footer.不过,你也不一定非要在每个页面或区块都放置这样一个元素。
Header和footer元素不会在大纲中创建新的节点,它们只用来标记页面中的区域。
总结
HTML5引入的新语义化元素将描述文档结构和大纲标准化。这为拥有HTML5浏览器而且需要大纲来帮助理解页面的人带来了极大的便利,比如需要使用辅助阅读技术的残障人士。这些新的语义化元素使用简单、副作用小,在非HTML5浏览器中也可以使用。
附加节:实际使用中div和section的区别
本小结引自集HTML5+CSS3网页布局教程-2大纲算法
1.何时使用div
div元素在html5之前是最常用的最流行的标签,但他本身是没有任何语义的,它只不过是用来布局页面和CSS样式以及JS调用。
如果是页面布局,且不是header、footer之类的专属区域,都应该使用div;
如果只是单纯的对一个段内容进行CSS样式定义,那么也应该使用div;
如果想对一段内容进行JS控制,那么也应该使用DIV;
2.何时使用section
在html5中,section标签并不是用来取代div的,他是具有语义的文档标签,表示一段文档中的章节,比如包含一个标题和一个段落,而大纲规范中,至少要包含一个标题。