[译] 不要再用这么多 div 了,试试语义化标签吧

原文连接:Stop using so many divs! An intro to semantic HTML,by Ken Bellowsphp

好多 div

咱们都喜欢使用 <div> 写网页。它已经存在几十年了。几十年来,当你出于样式或结构的考虑须要将一些东西包装到一块儿时,<div> 已经成为首选元素。如今的线上网站广泛能看到下面的代码结构:html

<div class="container" id="header">
    <div class="header header-main">Super duper best blog ever</div>
    <div class="site-navigation">
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </div>
</div>
<div class="container" id="main">
    <div class="article-header-level-1">
        Why you should buy more cheeses than you currently do
    </div>
    <div class="article-content">
        <div class="article-section">
            <div class="article-header-level-2">
                Part 1: Variety is spicy
            </div>
            <!-- cheesy content -->
        </div>
        <div class="article-section">
            <div class="article-header-level-2">
                Part 2: Cows are great
            </div>
            <!-- more cheesy content -->
        </div>
    </div>
</div>
<div class="container" id="footer">
    Contact us!
    <div class="contact-info">
        <p class="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </p>
        <div class="street-address">
            <p>123 Main St., Suite 404</p>
            <p>Yourtown, AK, 12345</p>
            <p>United States of America</p>
        </div>
    </div>
</div>
复制代码

用了不少 <div> 啊。无论怎么说,这样用也是有效的。个人意思是说,这是咱们须要的结构,并且也能依照设计完成样式写书。但这里面有些大问题:html5

  1. 可访问性:许多 a11y 工具都很聪明。它们会尽力解析页面结构,帮助用户按照开发者的意图浏览页面结构,并为用户提供轻松的跳转点(jump points),快速导航到页面的某个部分。但 <div> 并不能提供有关文档结构的任何有用信息。世界上最聪明的 a11y 工具说到底也不是人,不能指望它经过解析 class 和 id 就能明白全世界开发者各类怪异和狂野的命名方式。我能知道 class="article-header-level-2" 是一个副标题,但机器人不能。(若是真的能够,请你把它从个人计算机中请出,我尚未作好 AGI 革命 到来的准备。)
  2. 可读性:阅读上面的代码,咱们须要仔细查看类名,还要分清楚是哪一个 <div class="..."></div> 上的。不过,一旦进入到深几个层次的标记,就很难分清楚哪些 </div> 结束标记对应的 <div...> 开始标记在哪里。而后,咱们就很是依赖 IDE 提供的为 不一样的缩进级别着色突出显示匹配的标签 等功能,来搞清楚当前所处的位置。若是文档内容很长的话,可能还要借助大量滚动。
  3. 一致性和标准。当开始一项新任务或转移到一个新项目时,从头学习整个代码库中使用的全部疯狂标记约定可能会使人沮丧。若是你们都用一种标准化的方法来标记 Web 文档里的通用结构,那么即便对于不熟悉的代码库,咱们也能经过浏览 HTML 文件,快速了它的意思。这个标准就是 HTML5。

HTML5

HTML5 不是什么新东西了。简单介绍一下:它是在 2008 年 1 月(12 年前!)发布了最初的工做草案征求公众意见,并于 2014 年 10 月成为 W3C 推荐标准。也就是说,HTML5 正式存在都 5 年多了。dom

HTML5 的主要进步之一是引入了标准化的 语义元素。“语义”是指单词或事物的含义,所以“语义元素”就是为了用更有 意义的 方式标记文档结构的元素。语义标签能够清楚地代表元素的 用途 和在文档里所起的做用。并且,因为是标准化的,因此用这些元素定义文档,不只开发者,就连机器人都能顺利的理解和使用。ide

其实 HTML5 标准在 定义 <div> 元素时的一个 note 它的使用场景:工具

NOTE:post

除非是没有其余合适的元素了,强烈建议做开发者(Author)将 div 元素视为最后的选择。使用更合适的元素而非 div 能够为读者提供更好的可访问性,并且代码也更易维护。学习

— www.w3.org/TR/html5/gr…网站

我将语义块元素分为两类:主要结构(primary structure) 和  指示内容(content indicators)。这些不是标准术语,是我为这篇文章总结的,我认为这种区分更利于咱们学习。ui

主要结构

如今的互联网网站、教程甚至 CSS 库中可以找到一种超级通用的模式。页面的最顶层一般分为三个区域:headermainfooter,这些区域还能够进一步划分红不一样的 section。上面示例中代码就证实了个人观点:

<div class="container" id="的">...</div>
<div class="container" id="main">
    ...
    <div class="article-section">...</div>
    ...
</div>
<div class="container" id="footer">...</div>
复制代码

我已经看过(并使用)这个模式几十年了,以这种方式构造文档很是有意义,既能够提升 HTML 的可读性,也能够简化页面样式。header 和 footer 元素也能与 PHP 或 Rails/ERB 等语言中的部分模板更好的协做使用,好比你能够在整个站点中使用统一页眉和页脚:

<?php include 'header.php'; ?>

<div id="main">...</div>

<?php include 'footer.php'; ?>
复制代码

你们都以为这是一个很好的模式,包括在 WHATWG 和 W3C 的朋友们。因而 HTML5 就引入了 4 个看名字就知道其含义的标准化语义元素:<header><main><footer><section>

书立:<header> 和 <footer>

<header><footer> 元素是一对双胞胎:关于能够在文档里的哪里使用的规则在规范里的定义很类似,惟一的区别是:<header> 放在事物的开始,<footer> 放在事物的结尾。所谓“事物”,不只指页面的 元素:这对元素能够在文档中任何具备清晰开始和结尾的内容块中使用。这些内容块能够是表单、文章、文章中的某个部分、社交媒体网站上的帖子、卡片等。

<header> 和 <footer>  在语义上是在最近的 “secioning root”或“sectioning content”元素里使用的。这些元素由 <body><blockquote><section><td><aside> 和许多其余元素构成(若是须要查看完整的列表,请单击上面的连接)。辅助技术可使用这些元素和其余元素来生成文档的大纲,帮助用户更轻松地浏览文档。同时须要注意的是,每一个 sectioning root/content 只能有一个 <header><footer>(每一个最多出现一次,不可能同时两次)。

最后要注意的是,<header> 中一般会包含标题元素(<h1>~<h6>)。固然,不是必定要有的,但能够帮助其余相关元素与标题组合,好比:连接、图像或子标题。即便 <header> 中只包含一个标题元素,也能保持它在结构上的一致。

好东西:<main>

第三个主要的 regoin 元素是 <main>,它比较特殊。规范中对它作了两点重要说明:

文档的 <main> 包含该文档独一无二的内容。它不包括文档中的重复内容,好比网站导航连接、版权信息、网站 Logo、Banner 以及搜索表单(除非文档或应用的主要功能是表单搜索功能)。

www.w3.org/TR/html5/gr…

所以 <main> 中放置的是一个页面里好的、重要的内容,它是用户为何 访问这个页面的主要缘由,而不是你的站点。换句话说,主要内容。😯😲🤯

其余的像 Logo、搜索表单、导航啦这些东西能够放在 <body> 的 <header><footer> 里面,<main> 的外面。

一个文档中最多只能有一个 <main> 元素。若是文档中包含多个 <main> 元素,则其余的必须使用 hidden 属性 隐藏。

www.w3.org/TR/html5/gr…

这很独特。与 <header><footer>(以及大多数的其它块状元素)不一样的是,<main> 不能在整个页面里的任意 sectioning content 中使用,它能且只能使用一次。或者能够屡次使用,但一次只能让一个 <main> 元素可见,其它的则要经过 hidden 属性隐藏,效果等同于 CSS 的 display: none

细想一下,这个限制对在应用程序添加预加载视图的功能很是有用:建立一个新的 <main hidden>,获取用户接下里可能要查看的内容(例如,系列中的下一篇文章,幻灯片演示里的下一张幻灯片等等)。当用户单击连接/按钮时,经过切换当前 <main> 和预加载的 <main hidden> 中的 hidden 属性实现视图切换功能。

接下去讲以前,咱们先暂停一下,回顾下以前讲过的内容。文章开始的代码 ,使用 <header><footer><main> 修改以后,变为下面这样了:

<header>
    <h1>Super duper best blog ever</h1>
    ...
</header>
<main>
    <h2>Why you should buy more cheeses than you currently do</h2>
    ...
</main>
<footer>
    Contact us!
    <div class="contact-info">this.is.us@example.com</div>
</footer>
复制代码

很好!不过还有不少工做要作。

拆分:<section>

至此,咱们获得了页面的基本大纲:页眉、页脚和主要内容区域。如今是时候添加一些美妙的内容了。

咱们一般会将内容细分红多个 section,尤为是对下面这样,包含大量文本内容的文章。没有人喜欢阅读这样的文本墙。

没人喜欢读这样的文本墙

这就是引入 <section> 的意义所在。<section> 的规则是最简单的:结构上来讲,它基本上就是一个具备特殊的语义的 <div><section> 开启一个新的“sectioning content”区域,因此它能够有本身的 <header><footer>

那么,<section> 和普通 <``div``>之间的区别是什么。何时用 <div>,又是何时使用 <section> 呢?我再次引用规范来解答:

NOTE:

<section> 不是通用容器元素。若是这是为了样式目的或方便编写脚本代码,那么鼓励开发者使用 <div>。通常规则是,若是元素内容须要出如今文档 大纲 中,那么这些内容就要使用  <section> 元素包装。

www.w3.org/TR/html5/se…

顺便说一句,HTML5 规范很容易阅读。每次为了获得答案快速浏览时,我都会不可避免地学到一些意想不到的有用信息,尤为是在我开始点击连接时。有空试试看吧!

简而言之——若是你须要将这部份内容出如今目录中,那么就使用 <section> 吧;若是不须要,那就使用 <div> 或其余元素吧。

指示内容

咱们已经获得了一个结构牢固的页面了。没有只用 <div>,咱们明确标记了页面的主要内容区域,还标识了页眉、页脚和 section,可是绝对还有比咱们文档中使用的更多语义元素。

接下来,咱们再谈谈 HTML5 中添加的其它一些元素,这些元素传达的是 内容 语义而非 结构 语义。

彻底独立的内容:<article>

<article> 元素用来表示彻底独立的内容区域。这块内容区域即便被放入另外一个页面,仍然有意义。好比,这多是篇文章或帖子,但也多是一篇推文或者或 Facebook 墙贴之类的社交媒体内容。

HTML5 规范建议 <article> 都要有一个标题,来标识它的含义,最好使用标题元素(<h1>~<h6>)。<article> 元素中能够包含 <header><footer><section> 元素,所以你确实能够用它在另外一个页面中嵌入完整的文档片断及其须要的全部结构。

回到最初的例子,咱们使用 <article> 和讨论过的一些其余元素来重写 class="article-*" 元素。

<article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- cheesy content -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- more cheesy content -->
    </section>
</article>
复制代码

是否是可读性多了好多?不仅是更易于阅读了,辅助技术也能识别这个结构。机器人不能老是辨别出正确的类名含义,却能理解这些结构。

<nav>

这个元素比其余元素更出名。由于 <nav> 是为了清楚地标识页面上的主要导航块,帮助用户导航到网站的其余部分(好比站点地图或 <header> 中的连接列表)或导航当前页面(好比标识目录)。

上面的例子中,咱们为 <header> 中的连接应用 <nav>

<nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/archive">Archive</a>
</nav>
复制代码

修改没有改变页面结构,不须要看 <div> 的类名,就能一眼知道此处的含义,更重要的是,机器人也能理解了。

取得联系:<address>

咱们要讨论的最后一个元素是 <address>。这个元素用来标识联系信息,一般出如今主页的 <footer> 中。好比标记企业的邮寄地址、电话号码、客服邮件等。

有趣的是,如何标记 <address> 元素内容的规则是开放的。规范中提到其余一些规范能够解决了这个问题,而且提供这种粒度级别的内容可能超出 HTML 自己的范围。

常见的解决方案是 RDFa,也是一个 W3C 规范。它使用标签属性来标记数据的不一样组成部分。下面是咱们示例中的页脚代码在使用 <address> 元素和 RDFa 标记调整后的样子:

<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>
复制代码

RDFa 的写法确实有点冗长,但它对于标记数据很是方便。若是您想了解有关 RDFa 的更多信息,这里提供了几个连接:

总结

咱们到如今已经讲了不少了。把上面修改后的代码所有组合起来,就是下面这样啦。

<header>
    <h1>Super duper best blog ever</h1>
    <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </nav>
</header>
<main>
    <article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- cheesy content -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- more cheesy content -->
    </section>
</article>
</main>
<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>
复制代码

要我说,如今的写法比开始的写法可读性提升了 100 倍,同时对 SEO 和辅助设备也友好了 100 倍。

固然,HTML 中的语义元素决不止这些,还有许多其余的元素来帮助咱们标记和构造文本和嵌入式媒体等。若是你对语义标签的学习还未知足,想要更加深刻地了解。这里列出一些供你参考,其中一些也可能已经认识了:

本篇文章只是起了个头。当你开始阅读 HTML 规范时,发现根本停不下来。它是一门很是丰富的语言,我认为你们低估了 HTML 在网站里所起的做用。

(正文完)


广告时间(长期有效)

我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。

(完)

相关文章
相关标签/搜索