3.2 构建基本结构
HTML文档的主体部分包括了要在浏览器中显示的所有信息。这些信息需要在特定的结构中呈现,下面介绍网页通用结构的设计方法。
3.2.1 定义文档结构
HTML5包含一百多个元素,大部分继承自HTML4,新增加30个元素。这些元素基本上都被放置在主体区域内(<body>),我们将在各章节中逐一进行说明。
正确选用HTML5元素可以避免代码冗余。在设计网页时不仅需要使用div元素来构建网页通用结构,还要使用下面几类元素完善网页结构。
- h1、h2、h3、h4、h5、h6:定义文档标题,1表示一级标题,6表示六级标题,常用标题包括一级、二级和三级。
- p:定义段落文本。
- ul、ol、li等:定义信息列表、导航列表、榜单结构等。
- table、tr、td等:定义表格结构。
- form、input、textarea等:定义表单结构。
- span:定义行内包含框。
【示例】下面的示例是一个简单的HTML页面,使用了少量的HTML元素。它演示了一个简单的文档应该包含的内容,以及主体内容是如何在浏览器中显示的。
第1步,新建文本文件,输入下面的代码。
第2步,保存文本文件,命名为test,设置扩展名为.html。
第3步,使用浏览器打开test.html,可以看到如图3.5所示的预览效果。
图3.5 网页文档演示效果
为了更好地选用元素,读者可以参考w3school网站的http://www.w3school.com.cn/tags/index.asp页面信息。其中DTD列描述的是元素在哪一种DOCTYPE文档类型是允许使用的:S=Strict,T=Transitional,F=Frameset。
3.2.2 定义内容标题
HTML提供了六级标题用于创建页面信息的层级关系。使用h1、h2、h3、h4、h5或h6元素对各级标题进行标记,其中h1是最高级别的标题,h2是h1的子标题,h3是h2的子标题,以此类推。
【示例1】标题代表了文档的大纲。当设计网页内容时,可以根据需要为内容的每个主要部分指定一个标题和任意数量的子标题,以及子子标题等。
<h1> 唐诗欣赏 </h1> <h2> 春晓 </h2> <h3> 孟浩然 </h3> <p> 春眠不觉晓,处处闻啼鸟。 </p> <p> 夜来风雨声,花落知多少。 </p>
在上面的示例中,标记为h2的“春晓”是标记为h1的顶级标题“唐诗欣赏”的子标题,而“孟浩然”是h3,它就成了“春晓”的子标题,也是h1的子子标题。如果继续编写页面其余部分的代码,相关的内容(段落、图像、视频等)就要紧跟在对应的标题后面。
对任何页面来说,分级标题都可以说是最重要的HTML元素。由于标题通常传达的是页面的主题,因此,对搜索引擎而言,如果标题与搜索词匹配,这些标题就会被赋予很高的权重,尤其是等级最高的h1,当然不是说页面中的h1越多越好,搜索引擎还是足够聪明的。
【示例2】使用标题组织内容。在下面的示例中,产品指南有3个主要的部分,每个部分都有不同层级的子标题。标题之间的空格和缩进只是为了让层级关系更清楚一些,它们不会影响最终的显示效果。
在默认情况下,浏览器会从h1 ~ h6逐级减小标题的字号,如图3.6所示。在默认情况下,所有的标题都以粗体显示,h1的字号比h2的大,而h2的又比h3的大,以此类推。每个标题之间的间隔也是由浏览器默认的CSS定制的,它们并不代表HTML文档中有空行。
图3.6 网页内容标题的层级
提示:在创建分级标题时,要避免跳过某些级别,如从h3直接跳到h5。不过,允许从低级别跳到高级别的标题。例如,在“<h4>糕点 蛋卷 面包 薯片/膨化</h4>”后面紧跟着“<h2>粮油副食</h2>”是没有问题的,因为包含“<h4>糕点 蛋卷 面包 薯片/膨化</h4>”的“<h2>食品饮料</h2>”在这里结束了,而“<h2>粮油副食</h2>”的内容开始了。
不要使用h1 ~ h6标记副标题、标语以及无法成为独立标题的子标题。例如,假设有一篇新闻报道,它的主标题后面紧跟着一个副标题,这时,这个副标题就应该使用段落,或其他非标题元素。
<h1> 天猫超市 </h1> <p> 在乎每件生活小事 </p>
提示:HTML5包含了一个名为hgroup的元素,用于将连续的标题组合在一起,后来W3C将这个元素从HTML5.1规范中移除了。
上面的代码是标记文章副标题的一种方法。可以定义class属性,从而能够应用相应的CSS。该class属性可以命名为subhead等名称。
提示:曾有人提议在HTML5中引入subhead元素,用于对子标题、副标题、标语、署名等内容进行标记,但是未被W3C采纳。
3.2.3 使用div元素
有时需要在一段内容外围包一个容器,从而可以为其应用CSS样式或JavaScript效果。如果没有这个容器,页面就会不一样。在评估内容的时候,考虑使用article、section、aside、nav等元素,却发现它们从语义上来讲都不合适。
这时,真正需要的是一个通用容器,一个完全没有任何语义含义的容器。这个容器就是div元素,用户可以为其添加样式或JavaScript效果。
【示例1】下面的示例为页面内容加上div元素以后,可以添加更多样式的通用容器。
现在有一个div元素包着所有的内容,页面的语义没有发生改变,但现在我们有了一个可以用CSS添加样式的通用容器。
与header、footer、main、article、section、aside、nav、h1 ~ h6、p等元素一样,在默认情况下,div元素自身没有任何默认样式,只是其包含的内容从新的一行开始。不过,我们可以对div添加样式以实现设计。
div元素对使用JavaScript实现一些特定的交互行为或效果也是有帮助的。例如,在页面中展示一张照片或一个对话框,同时让背景页面覆盖一个半透明的层(这个层通常是一个div元素)。
尽管HTML用于对内容的含义进行描述,但div元素并不是唯一没有语义价值的元素。span元素是与div元素对应的一个元素:div元素是块级内容的无语义容器,而span元素则是短语内容的无语义容器,例如,它可以放在段落元素p之内。
【示例2】下面的代码为段落文本中的部分信息进行分隔显示,以便应用不同的类样式。
<h1>新闻标题</h1> <p>新闻内容</p> <p>......</p> <p>发布于<span class="date">2016年12月</span>,由<span class="author">张三</span>编辑</p>
提示:在HTML结构化元素中,div元素是除了h1~h6以外唯一早于HTML5出现的元素。在HTML5之前,div元素是包围大块内容(如页眉、页脚、主要内容、插图、附栏等),从而可用CSS为之添加样式的不二选择。之前div元素没有任何语义含义,现在也一样。这就是HTML5引入header、footer、main、article、section、aside和nav元素的原因。这些类型的构造块在网页中普遍存在,因此它们可以成为具有独立含义的元素。在HTML5中,div元素并没有消失,只是使用它的场合变少了。
对article和aside元素分别添加一些CSS,让它们各自成为一栏。然而,大多数情况下,每一栏都有不止一个区块的内容。例如,主要内容区第一个article元素下面可能还有另一个article元素(或section、aside元素等)。又如,也许想在第二栏再放一个aside元素显示指向关于其他网站的链接,或许再加一个其他类型的元素。这时可以将期望出现在同一栏的内容包在一个div元素里,然后对这个div元素添加相应的样式。但是不可以用section元素,因为该元素并不能作为添加样式的通用容器。
div元素没有任何语义。大多数时候,使用header、footer、main(仅使用一次)、article、section、aside或nav元素代替div元素会更合适。但是,如果语义上不合适,也不必为了刻意避免使用div元素,而使用上述元素。div元素适合所有页面容器,可以作为HTML5的备用容器使用。
3.2.4 使用id和class
HTML是简单的文档标记语言,而不是界面语言。文档结构大部分使用div元素来完成,为了能够识别不同的结构,一般通过定义id或class给它们赋予额外的语义,给CSS样式提供有效的“钩子”。
【示例1】构建一个简单的列表结构,并给它分配一个id,自定义导航模块。
使用id标识页面上的元素时,id名必须是唯一的。id可以用来标识持久的结构性元素,如主导航或内容区域;id还可以用来标识一次性元素,如某个链接或表单元素。
在整个网站上,id名应该应用于语义相似的元素以避免混淆。例如,如果联系人表单和联系人详细信息在不同的页面上,那么可以给它们分配同样的id名contact,但是如果在外部样式表中给它们定义样式,就会遇到问题,因此使用不同的id名(如contact_form和contact_details)就会简单得多。
与id不同,同一个class可以应用于页面上任意数量的元素,因此class非常适合标识样式相同的对象。例如,设计一个新闻页面,其中包含每条新闻的日期。此时不必给每个日期分配不同的id,而是可以给所有日期分配类名date。
提示:id和class的名称一定要保持语义性,并与表现方式无关。例如,可以给导航元素分配id名为right_nav,因为希望它出现在右边。但是,如果以后将它的位置改到左边,那么CSS和HTML就会发生歧义。所以,将这个元素命名为sub_nav或nav_main更合适。这种名称解释就不再涉及如何表现它。
对于class名称,也是如此。例如,如果定义所有错误消息以红色显示,不要使用类名red,而应该选择更有意义的名称,如error或feedback。
注意:class和id名称需要区分大小写,虽然CSS不区分大小写,但是在标签中是否区分大小写取决于HTML文档类型。如果使用XHTML严谨型文档,那么class和id名是区分大小写的。最好的方式是保持一致的命名约定,如果在HTML中使用驼峰命名法,那么在CSS中也采用这种形式。
【示例2】在实际设计中,class被广泛使用,这就容易产生滥用现象。例如,很多初学者为所有的元素定义class,以便更方便地控制它们。这种现象被称为“多类症”,在某种程度上,这和使用基于表格的布局一样糟糕,因为它在文档中添加了无意义的代码。
<h1 class="newsHead">标题新闻</h1> <p class="newsText">新闻内容</p> <p>......</p> <p class="newsText"><a href="news.php" class="newsLink">更多</a></p>
【示例3】在上面的示例中,每个元素都使用一个与新闻相关的class名称进行标识。这使得新闻标题和正文可以采用与页面其他部分不同的样式。但是,不需要用这么多class来区分每个元素。可以将新闻条目放在一个包含框中,并加上class名称news,从而标识整个新闻条目。然后,可以使用包含框选择器识别新闻标题或文本。
以这种方式删除不必要的类有助于简化代码,使页面更简洁。过度依赖class名称是不必要的,我们只需要在不适合使用id的情况下对元素应用class,而且尽可能少使用class。实际上,创建大多数文档常常只需要定义几个class。如果初学者发现自己定义了许多class,那么这很可能意味着自己创建的HTML文档结构有问题。
3.2.5 使用title
可以使用title属性为文档中任何部分加上提示标签。不过,它们并不只是提示标签,加上它们之后屏幕阅读器可以为用户朗读title文本,因此使用title可以提升无障碍访问功能。
【示例】可以为任何元素添加title,不过用得最多的是链接。
<ul title="列表提示信息"> <li><a href="#" title="链接提示信息">列表项目</a></li> </ul>
当访问者将鼠标指向加了说明标签的元素时,就会显示title。如果img元素同时包括title和alt属性,则提示框会采用title属性的内容,而不是alt属性的内容。
3.2.6 HTML注释
可以在HTML文档中添加注释,标明区块开始和结束的位置,提示某段代码的意图,或者阻止内容显示等。这些注释只会在源代码中可见,访问者在浏览器中是看不到它们的。
【示例】下面的代码使用“<!--”和“-->”分隔符定义了6处注释。
在主要区块的开头和结尾处添加注释是一种常见的做法,这样可以让一起合作的开发人员将来修改代码变得更加容易。
在发布网站之前,应该用浏览器查看一下加了注释的页面。这样能帮我们避免由于弄错注释格式导致注释内容直接暴露给访问者的情况。