本节书摘来自华章出版社《HTML 5与CSS 3 权威指南(第3版·上册)》一 书中的第3章,第3.3节,作者:陆凌牛,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.3 HTML 5中网页结构
前面两节详细介绍了在HTML 5中具体新增了哪些结构元素以及这些元素的定义和使用方法。在HTML 5中,可以使用这些结构元素来编排一份网页大纲,通过该网页大纲,我们可以一目了然地知道网页中具有哪些内容,网页中以什么样的结构形式来组织这些内容。
3.3.1 HTML 5中的大纲
在Word文档中,一份文档的大纲如下所示:
HTML 5网页文档中的大纲也基本如此,只不过使用不同的结构元素进行表达而已。换句话说,在HTML 5中,使用各种结构元素所描述出来的整个网页的层次结构,就是该网页的大纲。因此,在组织这份大纲的时候,不能使用div元素,因为div元素只能当作容器,用在需要对网页中某个局部使用整体样式时。
许多工具可以对HTML 5的网页文档进行分析,然后将该文挡中的大纲以可视化的形式展现出来。网站中就有一个文档大纲分析器,可以针对代码清单3-21中所示文档进行分析,分析结果如图3-4所示。
代码清单3-21 大纲分析工具测试用代码
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>大纲分析</title>
</head>
<section>
<h1>HTML5的基础知识</h1>
<section>
<h2>HTML5概述</h2>
(正文)
<section>
<h3>HTML5是什么?</h3>
(正文)
</section>
<section>
<h3>HTML5中的新增API</h3>
(正文)
</section>
</section>
<section>
<h2>HTML5快速入门</h2>
(正文)
<section>
<h3>HTML与XHTML</h3>
(正文)
</section>
</section>
</section>
图3-4中出现“1.Untitled Section”,是由于该网页文档中第一个元素即为section元素,缺乏整个网页标题元素。加入标题元素(<h1>元素)
,将代码清单3-21中的代码修改为代码清单3-22所示的代码,分析出来的大纲如图3-5所示。
代码清单3-22 添加了header元素后的大纲分析工具测试用代码
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>大纲分析</title>
</head>
<h1>HTML5的基础知识</h1>
<section>
<h2>HTML5概述</h2>
(正文)
<section>
<h3>HTML5是什么?</h3>
(正文)
</section>
<section>
<h3>HTML5中的新增API</h3>
(正文)
</section>
</section>
<section>
<h2>HTML5快速入门</h2>
(正文)
<section>
<h3>HTML与XHTML</h3>
(正文)
</section>
</section>
看到这里,你也许会问,如果光加一个<h1>
元素,就可以分析出标题来,那么还需要header元素干什么?答案是h1元素一般用来显示文字标题。事实上,在要定义为网页标题的整个内容中,往往并不只是显示一段文字而已,其中还包括了大量的导航条、企业LOGO图片、广告f?lash等,这些内容都可以放在一个header元素中,作为整个网页标题的内容,而标题文字为h1元素中的文字,在大纲中显示该标题文字。但是,这里要说明的是,header元素本身的作用不是被用来生成大纲的,大纲是依靠header元素中的h1~h6元素来生成的,如使用代码清单3-23中的代码生成的大纲如图3-6所示。
代码清单3-23 在企业网站中使用图片来显示企业名称
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>企业网站</title>
</head>
<header>
<img src="title.jpg" alt="用来显示企业名称的图片">
</header>
<section>
<h2>企业描述</h2>
(正文)
</section>
这里会产生这样一个问题,在很多企业网站(或其他网站)中,企业的标题并不是以文字来显示的,而是为了视觉效果,放在图片中显示的。难道这种情况就不能生成大纲了吗?笔者认为,这里有个小技巧,在header元素中,使用如下代码,既可以用图片来显示企业名称,又可以生成大纲。
<header>
<h1><img src="title.jpg" alt="企业名称"></h1>
</header>
在header元素中使用这段代码后,生成的大纲如图3-7所示。
与header元素相同,footer元素中如果没有标题元素(h1~h6元素)也不用于生成大纲。
在代码清单3-21或代码清单3-23中的代码底部追加如下代码,生成的大纲将不会有任何变化。
<footer>
版权所有:陆凌牛
</footer>
另外,对nav元素与aside元素来说,如果不在元素内部加入标题元素(h1~h6元素),生成大纲时会在该元素所在位置处添加一个“Untitled Section”的说明文字,但是根据HTML 5的开发文档记载,nav元素的作用为存放一组链接组,aside元素的作用为表示当前页面或文章的附属信息部分,允许不在这两个元素中添加标题,也就是说,大纲中存在对这两个元素的内容为“Untitled Section”的说明文字是合理的。
在代码清单3-21的代码底部添加如下代码,生成的大纲如图3-8所示。
<nav>
<ul>
<li><a href="#">链接测试1</a></li>
<li><a href="#">链接测试2</a></li>
</ul>
</nav>
<aside>
侧边栏中的内容
</aside>
另外,在HTML 5中,body元素、blockquote元素、f?ieldset元素、td元素、details元素及f?igure元素称为节根(sectioning root)元素。这些元素的共同特征是拥有自己独立的大纲,并且这些元素内的section元素、article元素、标题元素(h1~h6元素)、nav元素以及aside元素等,只用于生成其父元素的大纲时,而不用于生成父元素的上层祖先元素的大纲时。
在代码清单3-24中,blockquote元素内部有一个h1元素,正是因为这个h1元素是位于节根元素blockquote元素内部的,所以在针对blockquote元素的父元素body元素生成页面大纲时,该h1元素并没有显示在大纲中,如图3-9所示。
代码清单3-24 针对body元素生成大纲时节根元素中的子元素不起作用
<!DOCTYPE html>
<meta charset="UTF-8">
<body>
<h1>网页标题</h1>
<blockquote>
<h1>节根元素内部标题</h1>
</blockquote>
</body>
3.3.2 大纲的编排规则
关于内容区块的编排,可以分为显式编排与隐式编排两种方式。
1.?显式编排内容区块
显式编排是指明确使用section等元素创建文档结构,在每个内容区块内使用标题(h1~h6、hgroup等),如代码清单3-25所示。
代码清单3-25 显式编排内容区块示例
<body>
<h1>网页级内容区块标题</h1>
<p>网页级内容区块的正文</p>
<section>
<h2>section级内容区块的标题</h2>
<p>section级内容区块的正文</p>
</section>
</body>
2.?隐式编排内容区块
所谓隐式编排,是指不明确使用section等元素,而是根据页面中所书写的各级标题(h1~h6、hgroup)等自动创建各级内容区块。因为HTML 5分析器只要看到书写了某个级别的标题,就会判断存在相对应的内容区块。代码清单3-26为一个隐式编排内容区块的
示例。
代码清单3-26 隐式编排内容区块示例
<body>
<h1>网页级内容区块标题</h1>
<p>网页级内容区块的正文</p>
<!--分析器根据h2等元素判断生成内容区块-->
<h2>section级内容区块的标题</h2>
<p>section级内容区块的正文</p>
</body>
将这两种编排方式进行对比,很明显,显式编排更加清晰明确、易读。
3.?标题分级
不同标题之间是有级别的,h1的级别最高,h6的级别最低。隐式编排时按如下规则自动生成内容区块。
如果新出现的标题比上一个标题级别低,生成下级内容区块。
如果新出现的标题比上一个标题级别高或级别相等,生成新的内容区块。
第一条规则的示例与前面一样,现在我们来看关于第二条规则的示例,如代码清单3-27所示。
代码清单3-27 第二条规则示例
<body>
<section>
<h2>section级别的内容区块的标题</h2>
<p>section级别的内容区块的正文</p>
<!—因为下面的标题级别比上一个标题级别高,所以自动创建新的内容区块 -->
<h1>新的section级别的内容区块的标题</h1>
<p>新的section级别的内容区块的正文</p>
</section>
</body>
如果把上一个示例改成显式编排,代码如代码清单3-28所示。
代码清单3-28 第二条规则的显式编排示例
<body>
<section>
<h2>section级别的内容区块的标题</h2>
<p>section级别的内容区块的正文</p>
</section>
<section>
<h1>新的section级别的内容区块的标题</h1>
<p>新的section级别的内容区块的正文</p>
</section>
</body>
因为隐式编排容易让自动生成的整个文档结构与所想要的文档结构不一样,而且也容易引起文档结构混乱,所以尽量使用显式编排。
4.?不同的内容区块可以使用相同级别的标题
另外,不同的内容区块可以使用相同级别的标题。例如,父内容区块与子内容区块可以使用相同级别的标题h1。这样做的好处是,每个级别的标题都可以单独设计,如果既需要“整个网页的标题”,又需要“文章的标题”(譬如书写文档时),这样做将会带来很大的便利性,如同代码清单3-29所示。
代码清单3-29 不同的内容区块可以使用相同级别的标题
<body>
<h1>网页的标题</h1>
<article>
<header>
<hgroup>
<h1>文章标题</h1>
<h2>文章子标题</h2>
</hgroup>
<p>文章正文</p>
</header>
</article>
</body>
5.?网页编排示例
基于以上讲解过的知识点,我们来看应该怎样编排网页的内容。代码清单3-30为一个标准博客网页的示例,这个示例具备一个标准博客网页的基本要素,只缺少为了使用样式而补充添加的div元素。
代码清单3-30 网页编排示例
<!DOCTYPE html>
<head>
<title>网页编排示例</title>
<meta charset="UTF-8">
</head>
<body>
<!-- 网页标题 -->
<header>
<h1>网页标题</h1>
<!-- 网站导航链接 -->
<nav>
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="help.html">帮助</a></li>
</ul>
</nav>
</header>
<!-- 文章正文 -->
<article>
<hgroup>
<h1>文章主标题</h1>
<h2>文章子标题</h2>
</hgroup>
<p>文章正文</p>
<!--文章评论 -->
<section class="comments">
<article>
<h1>评论标题</h1>
<p>评论正文</p>
</article>
</section>
</article>
<!-- 版权信息 -->
<footer>
<small>版权所有:陆凌牛</small>
</footer>
</body>
这个示例使用了嵌套artilce元素的方式,将关于评论的article元素嵌套在主article元素中,在HTML 5中,推荐使用这种嵌套article元素的方式。
3.3.3 对新的结构元素使用样式
因为很多浏览器尚未对HTML 5中新增的结构元素提供支持,我们无法知道客户端使用的浏览器是否支持这些元素,所以需要使用CSS追加如下声明,目的是通知浏览器页面中使用的HTML 5中新增元素都是以块方式显示的,如下所示。
// 追加block声明
article, aside, dialog, f?igure, footer, header, legend, nav, section, main
{ display: block; }
// 正常使用样式
nav{f?loat;left;width:20%;}
article{f?loat:right;width:79%;}
另外,Internet Explorer 8及之前的浏览器不支持用CSS的方法来使用这些尚未支持的结构元素,为了在Internet Explorer浏览器中也能正常使用这些结构元素,需要使用JavaScript脚本,如下所示。
// 在脚本中创建元素
<script>
document.createElement("header");
document.createElement("nav");
document.createElement("article");
document.createElement("footer");
document.createElement("main");
</script>
<style>
// 正常使用样式
nav{f?loat;left;width:20%;}
article{f?loat:right;width:79%;}
</style>
尽管这段JavaScript脚本在其他浏览器中是不需要的,但它不会对这些浏览器造成什么不良影响。另外,到了Internet Explorer 9之后,这段脚本就不需要了。