HTML5区块和大纲算法
Posted felix930
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML5区块和大纲算法相关的知识,希望对你有一定的参考价值。
原文链接:
html5标准带来了几个带有标准语义的新元素来描述Web文档结构。本文会介绍这些元素,并且讨论如何用这些元素定义令人满意的文档大纲。
HTML4时代的文档结构
文档的结构(或者可以说在body标签之间的结构)是展示和表现web页面的基础。HTML4使用了区块(sections)和子区块(sub-sections)的概念来描述文档的结构。使用div元素来定义一个区块,并且使用标题元素(h1-h6)来定义这个区块的标题。它们之间的关系决定了web文档的结构和大纲。
下面的这些代码:
<div class="section" id="forest-elephants" >
<h1>Forest elephants</h1>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<div class="subsection" id="forest-habitat" >
<h2>Habitat</h2>
<p>Forest elephants do not live in trees but among them.
...this subsection continues...
</div>
</div>
可以提炼出如下的大纲:
1. Forest elephants
1.1 Habitat
定义一个大纲中的节点不一定非要使用div元素,其实,只要一个标题元素(h1-h6)就已经足够用来暗示一个节点了,所以这些标签:
<h1>Forest elephants</h1>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<h2>Habitat</h2>
<p>Forest elephants do not live in trees but among them.
...this subsection continues...
<h2>Diet</h2>
<h1>Mongolian gerbils</h1>
提炼出了如下的大纲:
2. Forest elephants
1.1 Habitat
1.2 Diet
3. 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)是什么级别,它总是离它最近的祖先区块的子节点。
译者例:
<body>
<h3>h3标题</h3>
<section>
<h1>h1标题</h1>
<p>从其他文档引入的section区块</p>
</section>
<div>
<h2>h2标题</h2>
<p>从其他文档引入的div区块</p>
</div>
</body>
上述代码提炼出的大纲如下:
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.显性定义节点
显性节点使用<body>、<section>、<article>、<aside>和<nav>这些标签来定义。
在HTML5中,每个节点都有它自己的标题分级标准。所以即使是一个嵌套的区块也可以用h1作为标题。详见“2.定义标题”部分
例:
<section>
<h1>Forest elephants</h1>
<section>
<h1>Introduction</h1>
<p>In this section, we discuss the lesser known forest elephants.</p>
</section>
<section>
<h1>Habitat</h1>
<p>Forest elephants do not live in trees but among them.</p>
</section>
<aside>
<p>advertising block</p>
</aside>
</section>
<footer>
<p>(c) 2010 The Example company</p>
</footer>
这段代码中section定义了一个顶级区块,顶级区块中定义了三个子区块(两个section和一个aside)。这段代码可以提炼出如下的大纲:
1. Forest elephants
1.1 Introduction
1.2 Habitat
1.3 Untitled Section
(译注:还记得吗?aside定义的节点也能出现在大纲中,但上例中并没有为aside定义标题,所以在大纲中出现了untitled section的字样)
2.定义标题
HTML的布局元素用来定义文档的结构,HTML的标题元素则用来给这些结构和这些结构所提炼的大纲赋予意义。
规则很简单:当前区块的第一个标题元素就是这个区块在大纲中节点的标题。
标题元素根据它元素名字里的数字来划分等级,其中h1等级最高,h6等级最低。标题元素等级只有在同一个区块中才有意义;决定大纲的是文档的区块结构,而不是标题元素的等级。举例来说,参考如下代码:
<section>
<h1>Forest elephants</h1>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<section>
<h2>Habitat</h2>
<p>Forest elephants do not live in trees but among them.
...this subsection continues...
</section>
</section>
<section>
<h3>Mongolian gerbils</h3>
<p>In this section, we discuss the famous mongolian gerbils.
...this section continues...
</section>
这些代码提炼出如下大纲:
1. Forest elephants
1.1 Habitat
2. Mongolian gerbils
(译注:之所以h3元素和h1元素同级,是因为h3所属的区块和h1所属的区块同级,这就说明了决定大纲的是区块结构,而不是标题元素的等级)
请注意标题元素的等级是不重要的(上例中h1是第一个顶级的区块的标题,h2是子区块的标题,h3是第二个顶级区块的标题)。任何等级的标题都可以用在显性区块里,但并不推荐这样做。
3.隐性定义节点
在HTML5中,并不是只能用这些区块定义元素来定义大纲,考虑到兼容统治了web很长时间的HTML4,HTML5制订了不使用区块定义元素而使用标题元素来定义的节点方法,并称之为隐性定义节点。
在一个显性定义的节点中,第一个标题元素是该显性节点的标题,从第二个标题元素开始(包括第二个标题元素),之后的标题元素会定义新的节点,这些新的节点就是隐性定义的节点(因为并没有用到显性定义节点的元素)。
隐性节点有可能作为同级节点或子节点存在,这取决于定义它的标题级别。
如果定义它的标题级别低于之前的标题级别,那么它作为子节点存在。看看代码:
<section>
<h1>Forest elephants</h1>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<h3 class="implicit subsection">Habitat</h3>
<p>Forest elephants do not live in trees but among them.
...this subsection continues...
</section>
提炼出下面的大纲:
1. Forest elephants
1.1 Habitat (通过h3元素隐性定义)
如果定义它的标题级别和之前的标题级别相同,它将关闭之前的节点并隐性定义一个同级别的节点:
<section>
<h1>Forest elephants</h1>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<h1 class="implicit section">Mongolian gerbils</h1>
<p>Mongolian gerbils are cute little mammals.
...this section continues...
</section>
提炼出下面的大纲:
1. Forest elephants
2. Mongolian gerbils (通过h1元素隐性定义,同时关闭之前的区块)
如果定义它的标题级别高于之前的标题级别,它将关闭之前的节点并隐性定义一个同级别的节点:
<body>
<h1>Mammals</h1>
<h2>Whales</h2>
<p>In this section, we discuss the swimming whales.
...this section continues...
<section>
<h3>Forest elephants</h3>
<p>In this section, we discuss the lesser known forest elephants.
...this section continues...
<h3>Mongolian gerbils</h3>
<p>Hordes of gerbils have spread their range far beyond Mongolia.
...this subsection continues...
<h2>Reptiles</h2>
<p>Reptiles are animals with cold blood.
...this section continues...
</section>
</body>
提炼出下面的大纲:
1. 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.
举例来说:
<section>
<h1>Forest elephants</h1>
<section>
<h2>Introduction</h2>
<p>In this section, we discuss the lesser known forest elephants</p>
</section>
<section>
<h2>Habitat</h2>
<p>Forest elephants do not live in trees but among them. Let's
look what scientists are saying in "<cite>The Forest Elephant in Borneo</cite>":</p>
<blockquote>
<h1>Borneo</h1>
<p>The forest element lives in Borneo...</p>
</blockquote>
</section>
</section>
上面的代码提炼出如下的大纲:
1. 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的区别
1.何时使用div
div元素在html5之前是最常用的最流行的标签,但他本身是没有任何语义的,它只不过是用来布局页面和CSS样式以及JS调用。
- 如果是页面布局,且不是header、footer之类的专属区域,都应该使用div;
- 如果只是单纯的对一个段内容进行CSS样式定义,那么也应该使用div;
- 如果想对一段内容进行JS控制,那么也应该使用DIV;
2.何时使用section
在html5中,section标签并不是用来取代div的,他是具有语义的文档标签,表示一段文档中的章节,比如包含一个标题和一个段落,而大纲规范中,至少要包含一个标题。
以上是关于HTML5区块和大纲算法的主要内容,如果未能解决你的问题,请参考以下文章