Dive Into HTML5:它的含义是什么?(续四)

Headers

在 HTML 4 的页面中,我们通常会对 header 有这么一段描述:

<div id="header">
  <h1>My Weblog</h1>
  <p class="tagline">A lot of effort went into making this effortless.</p>
</div>

…

<div class="entry">
  <h2>Travel day</h2>
</div>

…

<div class="entry">
  <h2>I'm going to Prague!</h2>
</div>

这么使用标签并没有什么错误。如果你喜欢,你可以继续这么去用。在 HTML 5 中,这也是允许的。但是,前面我们也说过,HTML 5 同样提供了一些额外的更具语义的标签,比如 header 和 section。

首先,我们先来看看<div id="header">。这是一种最经典的实现模式,但它没有什么意义。dev 标签不具备任何语义(用户探针不会从 id 属性获取任何信息)你完全可以把它替换成<div id="shazbot">,这同前面的写法完全一样,没任何意义。

为解决这个问题,HTML5 定义了<header>标签。这个 HTML5 标准给出了一个真实案例。下面则是我们上面代码的 HTML5 版本:

<header>
<h1>My Weblog</h1>
<p>A lot of effort went into making this effortless.</p>
…
</header>

很好!它告诉人们,这是一个 header。但是标语 tagline 呢?这是另一个常见的模式,至今依然没有标准标签。因为它很难给一个标签。标语类似于副标题,但是它需要“附加到”主标题上。这意味着,副标题不应该创建自己的块。

类似<h1><h2>的标签可以方便你创建良好的页面结构。使用这种标签,你可以为自己的页面创建一个可视化的大纲。屏幕阅读器可以利用这种文档大纲来帮助读者导航你的页面。现在有很多在线的或者浏览器扩展能够帮助你对文档大纲进行可视化操作。

在 HTML 4 中,<h1><h6>是唯一的能够创建文档大纲的元素。一个文档大纲类似于:

My Weblog (h1)
   |
   +--Travel day (h2)
   |
   +--I'm going to Prague! (h2)

这挺好,但是却没有显示出“A lot of effort went into making this effortless.”这个副标题。我们可以试着用<h2>,这样就可以了:

My Weblog (h1)
   |
   +--A lot of effort went into making this effortless. (h2)
   |
   +--Travel day (h2)
   |
   +--I'm going to Prague! (h2)

但是,这并不是文档的正确结构。副标题不是一个独立的段落,它仅仅是一个副标题。副标题怎么能和其它标题并列呢?

或许我们应该把副标题当做<h2>,然后把文章的其它标题作为<h3>?不不不,这只会让文档结构变得更糟:

My Weblog (h1)
   |
   +--A lot of effort went into making this effortless. (h2)
         |
         +--Travel day (h3)
         |
         +--I'm going to Prague! (h3)

现在我们的文档大纲有一个虚假的节点,这个节点却把本应属于根节点的元素“偷到”自己名下。问题关键在于,HTML 4 没有在文档大纲中提供副标题的位置。不管我们怎么尝试,“A lot of effort went into making this effortless”都会成为一个独立的部分。这就是为什么我们得使用没有任何相关语义的<p>标签来表明副标题。

HTML5 提供了一种解决方案:<hgroup>元素。<hgroup>可以把两个或者多个相关的标题组织在一起。什么是“相关”?“相关”是说,在文档大纲中仅会创建一个独立的节点。下面就是我们的实例:

<header>
  <hgroup>
    <h1>My Weblog</h1>
    <h2>A lot of effort went into making this effortless.</h2>
  </hgroup>
  …
</header>

…

<div class="entry">
  <h2>Travel day</h2>
</div>

…

<div class="entry">
  <h2>I'm going to Prague!</h2>
</div>

此时,我们的文档大纲是这样的:

My Weblog (h1 of its hgroup)
   |
   +--Travel day (h2)
   |
   +--I'm going to Prague! (h2)

现在,你可以使用 HTML5 Outliner 来测试一下你的页面,看看标题部分是不是正确的了。

Articles

继续来编写我们的文章。一般正文部分都会这么去写:

<div class="entry">
  <p class="post-date">October 22, 2009</p>
  <h2>
    <a href="#"
       rel="bookmark"
       title="link to this post">
       Travel day
    </a>
  </h2>
  …
</div>

当然,在 HTML5 中你依然可以这么写,但是 HTML5 也提供了更具语义的标签,用于标记页面的正文部分,这就是<article>

<article>
  <p class="post-date">October 22, 2009</p>
  <h2>
    <a href="#"
       rel="bookmark"
       title="link to this post">
       Travel day
    </a>
  </h2>
  …
</article>

不过还不仅仅是这么简单。你还应该再改变另外一个东西。我们先看看还得怎么做,然后再解释为什么要这么做:

<article>
  <header>
    <p class="post-date">October 22, 2009</p>
    <h1>
      <a href="#"
         rel="bookmark"
         title="link to this post">
         Travel day
      </a>
    </h1>
  </header>
  …
</article>

注意到了吗?我们将<h2>换成了<h1>,并且把标题用<header>围了起来。我们已经解释过<header>的作用。我们这么做的目的是,将文章所有用于表示标题的元素用<header>包围起来(在这个例子中,就是发布日期和标题这两部分)。但是,每一篇文档中难道不应该只有一个<h1>吗?这难道不会打乱文档大纲?不会。但是为了理解为什么不会,我们还得从头说起。

在 HTML 4 中,创建文档大纲的唯一方式就是<h1><h6>标签。如果你希望大纲中只有一个根节点,就不得不保证只有一个<h1>标签。但是 HTML5 标准定义了一个算法,用于生成新语义下的文档大纲。这个算法会将<article>当做一个新的块,也就是说,作为文档大纲的一个新的节点。而在 HTML 5 中,每一个块都能够有其自己的<h1>元素。

这对 HTML 4 是一个巨大的改变。为什么要这么做呢?现在很多 web 页面都是由模板生成的。页面内容是由同一段代码提供,并且插入到页面切当的位置。很多教程都是这么说的:“这是一些 HTML 标签。把它们复制到你的页面就可以了。”这对于内容比较少的页面是适合的,但是,如果你复制的是一整块呢?这种情况下,我们就得这么理解教程:“这是一些 HTML 标签。把它们复制到一个文本编辑器中,修改一些它们的标题,以便能够和你的页面正确地组成多级标题,然后再把它们粘贴到你的页面。”

让我们从另外一个方向去理解。HTML 4 没有通用的标题元素。它只有六个级别的标题标签,也就是<h1><h6>。这些标题应该正确的按顺序进行嵌套。这对于你“修改”页面,而不是“自己编写”页面来说简直是一个灾难。这个问题由 HTML 5 使用新的块元素和新的标题规则解决了。如果你使用新的块元素,我们可以这么来写:

<article>
  <header>
    <h1>A syndicated post</h1>
  </header>
  <p>Lorem ipsum blah blah…</p>
</article>

好了。你把它复制到你的页面吧!不需要做任何修改。事实上,即使它有一个<h1>标签也没有任何问题,因为整个代码都被包裹在<article>里面。<article>定义了一个在文档大纲中自容纳的节点。<h1>仅仅为这个大纲节点提供标题,页面中其他的块元素都会像原来一样正确工作。

对于 web 上的所有东西,真实性是比其他部分更加复杂的。新的“显式的”块级元素,比如能够包围<h1><article>,比起旧的“隐式的”块级元素(<h1>-<h6>)的行为表现不一致。如果仅仅使用其中一种,而不是两个同时使用,你的开发会更加简单。但是,如果你不得不在同一个页面混用,记得及时使用 HTML5 Outliner 进行检查,以保证你的页面具有正确的文档大纲。

Leave a Reply