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