【译】中止滥用div! HTML语义化介绍

banner

DIVS该中止(滥用)了

咱们喜欢(使用)<div>标签。它们已经存在了几十年,这几十年来,当须要将一些内容包裹起来达到(添加)样式或者布局目的的时候,它们成为首选元素。查看线上站点时,看到像下面这些内容的状况依旧很常见:php

<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>
复制代码

Hoo,那有不少的div标签。可是,它有效。个人意思主要是,它具备你须要的结构。而且,我肯定在你完成样式添加以后,它看起来会像你想要的那个样子。然而,它有些严重的问题:html

  • 可访问性 - 许多a11y tools很是智能,会尽力解析页面结构,以帮助用户按照页面制做者的意图来引导用户,并为用户提供简单的跳转连接来指引他们到本身关心的页面部分。然而,<div>标签并无真正传递有关文档结构的任何有用信息。世界上最聪明的a11y tool仍然不是人类,不能期望其解析classid属性,或可以识别全世界开发人员命名块元素的奇怪和狂野的方式。我能够识别到class="article-header-level-2"是一个副标题,可是机器不能。(若是能够的话,把它从我电脑中拿出来,可我也还没准备好进行AGI革命呢。)html5

  • 可读性 - 要阅读此代码,你须要仔细扫描类名,从<div class="..."></div>样板之间挑选出来。一旦你(的代码)深刻几个层次,跟踪哪一个</div>结束标记与哪一个<div ...>开始标记对应,那就变得很棘手了。你开始很是依赖IDE功能,例如着色不一样的缩进级别突出显示匹配的标记以跟踪您的位置,而在较长的文档中,它可能须要在这些功能之上进行大量的滚动。git

  • 一致性和标准 - 开始新的工做或转移到新项目,而且必须从头学习代码库中使用的让人抓狂的标记,那可能会使人很沮丧。若是每一个人都有标准化的方法来标记web文档中常见结构,那么在不熟悉代码库的状况下,均可以很容易的浏览HTML文件并快速处理它应该展现的内容。若是只有一个这样的标准...github

HTML5: 这个标准

HTML5并不新奇。这是轻描淡写;最初的工做草稿于2008年1月(11年前)发布,以征求公众意见,并于4年半前,2014年10月份成为一个全面W3C的推荐。因此,就像它已经存在了一段时间。web

HTML5的主要进步之一是引入了一组标准化的语义元素。术语“语义”指的是单词或事物的含义,所以”语义元素“是用于以更有意义的方式标记文档结构的元素,这种方式能够清楚地代表它们的用途和它们在文件中服务的目的是什么。并且重要的是,因为它们是标准化的,定义文档的这些元素能够被每一个人使用并理解,包括机器人。dom

我认为HTML5规范自己在<div>元素定义下的一个注释中很好地总结了这个问题:ide

注释: 强烈建议做者将div元素视为最后采起的元素,在没有其它元素适合的(状况下)。使用更合适的元素而不是div元素可使读者更容易访问,而且更容易为做者提供可维护性。-- www.w3.org/TR/html5/gr…布局

我将语义块元素分为两类:主要结构内容指标。这些不是标准的条款或者其它条款;我在这篇文章中作了一些(区分)。但我认为这种区分足够有用。🤷‍♂️post

主要结构

有一个超级常见的模式,可在互联网上的网站,教程甚至CSS库中找到,而且有充分的理由。咱们常常将最顶层的页面划分为三个区域:页眉主页页脚,而后根据须要将这些区域划分为多个区域。我在上面的例子中包含了这个来证实这点:

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

我已经看过(而且使用过)这种模式好久了,以这种方式构造文档很是有意义,既能够读取HTML,又能够更加简单地在CSS中设置页面样式。页眉和页脚元素页可使用PHP或Rails/ERB等语言中的部分模版来更易于使用,由于你能够在整个站点中包含常见的页眉和页脚部分:

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

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

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

因此这就是事情:每一个人都认为这是一个很好的模式。这包括WHATWGW3C的人员,他们将模式标准化为HTML5中的四个新元素,名称很是清晰:<header>, <main>, <footer><section>

Bookends: <header><footer>

<header><footer>元素基本上是双胞胎:它们在规范中的定义很是类似,并遵循相同的规则,关于它们被容许使用的位置,惟一区别在于它们的语义目的:页眉在事物的前面,页脚在事物的末尾。对于事物,个人意思不只仅是页面的: 这对元素的设计用于文档的任何部分,表明一大块内容,具备明确的开头和结尾。这能够包括表格,文章,文章部分,社交媒体网站上的帖子,卡片等。

页眉和页脚在语义上接近sectioning rootsectioning content元素。像<body>, <blockquote>, <section>, <td>,<aside>等许多其它元素;若是你想了解完整的列表,就点击上面的连接。辅助技术可使用这些元素和其它元素生成文档大纲,这能够帮助用户更轻松的访问它。在每一个sectioning root/content中,你不该该使用超过一个的<header><footer>。(一个就好,不能两个相同)

做为最后说明,<header>常常做为其上下文保存标题元素(<h1>-<h6>)。这不是必须的,但能够帮助将其它相关元素与标题分组,好比连接,图片或子标题,而且能够维持一直的结构,即便标题是<header>中的惟一元素。

好东西:<main>

第三个主要区域元素--<main>很特别。规范中说明了关于<main>的两个很是重要的内容:

文档的主要内容区域包括文档的特定内容,且不包括在一组文档中重复的内容,例如站点导航连接,版本信息,站点的徽标,横幅和搜索表单(除非文档或应用的主功能是一种搜索形式)-- www.w3.org/TR/html5/gr…

因此,<main>是你放置好东西的区域,是页面的重要部分,特别是用户访问此页面的缘由(或说目的),而不是您的站点。换句话来讲,主要内容。😯😲🤯

全部其它东西,徽标、搜索表单和导航栏等均可以在<body>中的<header><footer>中,可是在<main>以外。

文档中不能有多个可见的main元素。若是文档中存在多个main元素,则必须使用隐藏属性隐藏全部其它(main)实例。 -- www.w3.org/TR/html5/gr…

这很独特。和<header><footer>(以及其它块元素不一样),<main>不能在任意切片内容的整个页面中使用;它应该只被使用一次。或者更确切地说,它能够在文档中屡次被使用,可是一次只能看到一个<main>元素,全部其它的(

)必须被使用隐藏属性隐藏,如CSS中的 display:none。若是您思考下,(你会明白)这在应用程序中预加载视图是种颇有用的模式:建立一个新的 <mian hidden>,获取用户可能接下来查看的一些内容(例如:系列文中的下一篇,下一张幻灯图放映等),而后,当用户点击 连接/按钮加载该视图时,经过在二者上切换 隐藏属性,将当前的 <main>切换到预加载的(那个)。

在继续以前,咱们暂停下并查看上面的示例。若是咱们使用<header><main><footer>做为文章的主要结构,它的外观以下:

<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>

所以,咱们为页面提供了一个基本大纲:页眉,页脚和主要内容区域。如今是时候添加些美妙的内容了。

一般,你会但愿将你的内容分解为多个部分,尤为是对像本文这样的大量文本内容,由于没人喜欢阅读这些难以理解的文本墙。

Nobody likes a wall of text

<section>派上用场了。这是在系列规则中最简单的一个:从结构上讲,它基本上只是一个具备特殊含义的<div>。一个<section>开始一个新的"sectioning content"区域,所以它能够有本身的<header><footer>

那么,<section>和普通的旧<div>之间有什么区别,而后,你应该在何时使用它们呢?好吧,容许我再次引用规范:

笔记:

元素不是通用容器元素。当一个元素仅是用于样式目的或为脚本编写提供便利的时候,鼓励做者使用[div](https://www.w3.org/TR/html5/grouping-content.html#elementdef-div)元素。通常规则是
元素仅在元素内容在文本[大纲](https://www.w3.org/TR/html5/sections.html#outline)中明确列出时候才适用。-- [https://www.w3.org/TR/html5/sections.html#the-section-element](https://www.w3.org/TR/html5/sections.html#the-section-element)

你知道,概述来讲,HTML5规范其实是可读的。它是那个比较可读的规范之一。每当我浏览它以获取快速答复时,我都不可避免地学到一些意想不到的和有用的东西,尤为是当我开始点击连接的时候。有时(你也)试试吧!

简而言之,若是要在目录中列出文档的一部分,请使用<section>。若是没有,请使用<div>或其它元素。

内容指标

很好,咱们已经获得了一个坚固的页面结构。咱们已经明确标记了页面的主要内容区域,而不只仅是单独调整<div>,咱们已经调整出了页眉,页脚和章节。可是,确定还有比咱们的文档更多的语义。

让咱们来谈谈HTML5中添加的一些元素,它们传达的内容语义而不是结构。

总体:<article>

<article>元素用于表示彻底独立的内容区域,这些内容能够从页面中提取出来并放入另外一个内容中,而且仍然有意义。这多是文字文章或博客,但也可用于社交媒体帖子,如推特或脸书的墙贴。

HTML5规范建议文章总有一个标题,标识它是什么,理想的状况下使用标题元素(<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>旨在清楚地识别页面上的主要导航块,帮助用户围绕站点其他部分找到路径的连接组(例如站点地图或标题中的连接列表)或当前页面(例如目录)。

在咱们的示例顶部,让咱们将<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倍,并且对于搜索引擎优化和可访问性目的而言,其效率将提升100倍。

这些毫不是HTML中惟一的语义元素。有不少其它元素能够帮助你标记和构建你的文本内容,嵌入媒体资源等等。若是你喜欢这个而且但愿深刻挖掘,这里有一些(标签)能够查看下。你可能认识一些:

这只是一个开始!就像我说的,当你开始阅读HTML规范时,很难停下来。它是种很是丰富的语言,我认为人们常常会低估这种语言。

原文: dev.to/kenbellows/…

文章首发:github.com/reng99/blog…

更多内容:github.com/reng99/blog…

相关文章
相关标签/搜索