HTML5语义化

编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中。

语义

HTML没有给我们提供大量的标签去使用。其可选择的数量就像是街边的小商店而不是沃尔玛。

我们有段落,列表和标题,但是我们不具有事件,新闻故事,或者说是配方。HTML提供给我们一个元素用于字符串的缩写标记,但是没有提供我们一个元素用于数字的价格标记。

显然,从各种各样惊人的网站就可以看出,这一限制并没有得到很好的解决。虽然HTML并没有提供我们一个明确的元素用于内容价格的标记,但是他现在也已经变得十分灵活以至于“足够好”。

这里套用Winston Churchill经常说的一句话,HTML是尝试过的标记形式中最糟糕的一种。

可扩展性

其他的标记语言允许你创建你想要的任何元素。在XML之中,如果你想创建一个 event 元素或者一个 price 元素,你可以直接去创建。其缺点在于你必须告诉解析器 event 或者 price 的含义。HTML中有限的元素限制就成为了一个优点,因为用户代理知道每一个元素的含义。浏览器有一个内置的对HTML的理解。所以我们自定义元素名称是不被允许的。

HTML 提供了一个方便的例外条款,它允许网页设计者向元素添加更多的语义值:class 属性。这个属性允许我们向元素添加特殊的实例标签,使其成为一个特殊的类或者元素类型。

关于这一点,你可能会说“等等,是不是CSS中的类?”你只是说对了一半,CSS类选择器只是使用class属性的一个例子,并不是使用class的唯一原因。类也可以在脚本中使用。如果类名遵守商定的约定,他们甚至可以在浏览器中使用,如微格式(microformats)。

微格式

微格式是一组由社会商定的公约。这些格式使用class 属性来弥补HTML的一些漏洞:用于详细联系的 hCard,用于事件的 HCalendar,用于新闻故事的 hAtom。因为类名已经被社会商定,所以现在的解析器和浏览器扩展根据这些特定的模式进行工作。

微格式的设计已经被限制。他们不能尝试解决每一个可能的用例。相反,他们的目标是“低果实”,即用20%的努力就可以解决80%的问题。决定果实的质量,如“语义化标签”是十分简单的,仅仅了解已经被标记的内容就可以。换句话说就是,道路已经被平铺了。

是不是听起来很熟悉?HTML5的设计理念和微格式十分类似。事实上,我所描述的由社区商定的微格式的约定可以很容易的被应用到HTML5之中。

沸腾的海洋

开发微格式进程方式的模板应用到HTML5的开发当中可能并不能满足每个人的要求。但是80/20的法则对于class命名足矣,对于世界上最好的标记语言是不是最好的呢?

有些人认为,HTML需要具有无限的扩展性。这就意味着他不能很好地解决大多数的用户问题。语言应该可以解决用户的每一个问题。

也许对于这种可扩展性最有说服力的论据就是John Allsopp在“Semantics in HTML5”中定义:

我们不需要在HTML词汇中添加特定的术语,我们需要添加一种机制,允许需要的语义被添加到文档中。

现有的技术已经可以做到这一点。RDFa 允许作者在HTML文档中嵌入自定义词汇。但是不同于微格式只可以使用已经约定好的类名,RDFa 可以使用多种格式进行命名。所以微格式可能使用这样子的标记<h1 class="summary">,而RDFa则可以使用<h1 property="myformat:summary">这种方式。

毫无疑问,RDFa的功能更为强大,但是他的表现是需要代价的。与HTML的简单相比,RDFa的命名空间引入了格外复杂的一层。

对于命名的争论并不稀奇。在几年前的一篇博客中,Mark Nottingham 讲述了潜在的破坏性的副作用:

关于HTML扩展,我发现的有趣点是命名空间是没有必要的;Netscape增加了blink,MSFT增加了marquee,等等。从一开始我就提出在HTML中添加命名空间在不同浏览器之中将具有不合法化和制度化,而这种差异使用同一种方案是不能解决的。

不是无限的可扩展性,这是基于社区共识最有力的论据。

HTML5可能会以某种方式对固有语义进行扩展。class属性依然存在,所以微格式将继续工作。HTML5也可能与RDFa进行兼容,或者使用自己的“微”词汇。

在这两种情况下,大多数的网页设计者对这种可扩展性可能并不感兴趣。真正重要的由社区商定并由浏览器厂商实现的固有语义。

新元素

HTML5 引入了一些新的内联元素,来完善我们固有的span, strong, em, abbr等元素。奥~ 现在我们不称之为内联元素了,取而代之,他们现在是“文本级语义”。

mark

在浏览搜索的结果列表中,你会经常看到每一个搜索结果中会突出显示搜索词。你可以使用span元素对每个实例进行标记,但是span只是语义的拐杖,你可能会在样式上投入更多的精力。

你可以使用em或者strong,但是这并不具有语义化。你不想再搜索词上添加任何标记只是希望其以某种方式突出显示。

添加mark元素:

<h1>Search results for 'unicorn'</h1>
<ol>
    <li><a href="http://clearleft.com/">
        Riding the UX <mark>unicorn</mark>
        across the rainbow of the web.
    </a></li>
</ol>

mark元素对其内容赋予任何重要性,仅仅是突出显示。规范解释为mark是指“文字标注或由于关联与另一个上下文,强调引用”

mark元素也可以在非搜索环境中使用,但是我还没有想到一个很好的使用环境。

time

hCalendar是最流行的微格式之一,因为它触及了一个非常普遍的库:标记了事件,所以用户可以直接将它们添加到日历之中。

hCalendar中最棘手的一个问题就是日期和时间是以机器可读的方式被描述的。人类喜欢的描述方式为5月25或者下一个星期三,但是在IOS中机器解析的格式为:YYYY-MM-DDThh:mm:ss

微格式社区想出了一些解决问题的对策,如使用abbr元素:

<abbr class="dtstart" title="1992-01-12">
    January 12th, 1992
</abbr>

如果abbr元素的使用方式令你感到恶心,使用一些类-值 模式也可以打破机器解析的方式。在HTML5中,time元素的使用解决了这个问题。

<time class="dtstart" datetime="1992-01-12">
    January 12th, 1992
</time>

time元素可以被用于日期,事件或者是两者的结合:

<time datetime="17:00">5pm</time>
<time datetime="2010-04-07">April 7th</time>
<time datetime="2010-04-07T17:00">5pm on April 7th</time>

meter

meter元素可用于测量的标记。提供测量的最大值和最小值进行测量值的缩放。

<meter>9 out of 10 cats</meter>

如果你不想暴露最大值,你可以使用max属性代之。

<meter max="10">9 cats</meter>

相应的还有一个min属性。同时你也可以使用high,lowoptimum属性。如果你愿意,你甚至可以使用value属性隐藏隐藏其自身的测量值。

<meter low="-273" high="100" min="12" max="30" optimum="21" value="25">
    It's quite warm for this time of year.
</meter>

progress

你可以使用meter元素对已测量值进行很好地解释。你也可以使用progress元素对正在改变的值进行说明:

Your profile is <progress>60%</progress> complete.

同样的,如果你想使用,这里也具有min,max以及value属性:

<progress min="0" max="100" value="60"></progress>

progress元素与DOM脚本结合使用是最有用的。你可以使用Javascript动态更新值,在对Ajax文件上传时便于浏览器可以及时向用户传达进度。

结构体

早在2005年,谷歌就做了一些研究,在网页平铺的道路上可以找出什么样的“语义化标签”呢?

解析器浏览了超过十亿的网页和表格中最常见的类名。结果令人十分吃惊。header, footer, 以及 nav 的类名最为普遍。这些新兴的语义很好地映射到了HTML5引入的新结构元素之中。

section

section元素用于组合一些主题相关的内容。这听起来很像用作通用容器的div元素。不同之处在于div没有语义,他不能告诉你内容是什么。相对而言,section元素可以明确地告诉你其内部相关内容。

你可能可以使用section元素来替代div元素,但是替换之前记得提醒自己“所有的内容是否相关?”

<section>
    <h1>DOM Scripting</h1>
    <p>The book is aimed at designers rather than programmers.</p>
    <p>By Jeremy Keith</p>
</section>

header

HTML5规范中描述header元素为“一组解释性或导航型性的条目。”这听起来很合理。一般这部分内容我希望去报头中寻找,同时header一次常被用来报头的代名词。

HTML5之中的header元素与普遍接受的header或者masthead单词之间存在关键区别。 网页中通常只有一个报头,但是文档中可以有多个header元素。例如,你可以在section元素中使用header元素。事实上,你应该在section元素内使用一个header元素。规范中描述:section元素作为“主题内容的分组,典型的需要一个标题。”

<section>
    <header>
        <h1>DOM Scripting</h1>
    </header>
    <p>The book is aimed at designers rather than programmers.</p>
    <p>By Jeremy Keith</p>
</section>

header通常出现在在文档或者section的头部,但是这并不是必须的。它是由介绍的内容以及是否具有导航作用来决定的,而不是其位置决定的。

footer

类似于header元素,footer元素听起来也是由其位置决定的,但是和header一样,不具有决定性。相反,footer元素中应该包含类如此类信息:作者、出版权信息以及相关内容信息,等等。

footer这个词可以很好的在网页设计者心中留下一个映射。但是不同的是,我们在整个文档中只使用一个fooetr,但是HTML5允许我们在section中使用footer元素。

<section>
    <header>
        <h1>DOM Scripting</h1>
    </header>
    <p>The book is aimed at designers rather than programmers.</p>
    <footer>
        <p>By Jeremy Keith</p>
    </footer>
</section>

aside

header元素匹配报头部分,aside元素匹配侧边栏部分。但是,这里我所提及的aside与位置无关。仅仅因为一些内容出现在主内容的左边或者右边不足以使用aside元素。再次强调,它与内容相关,与位置无关。

aside元素应该被用于无关内容。如果你有你认为应该与主内容分开的内容,那么aside元素是你应该正确考虑使用的元素。询问你自己aside元素中的内容是否可以被独立开来而不会影响文档或者section中主内容的含义。

Pullquotes是关于无关内容的一个很好例子。这部分内容的存在是很好的,但你也可以删除它们而不会影响对主要内容的理解。

请记住,仅仅因为你的视觉设计需要一些内容在侧边栏出现并不一定意味着aside元素是正确的包含元素。 例如,侧边栏部分出现一个作者的介绍是很常见的。 类似于这种数据使用footer元素是最适合的--规范明确提到作者的信息适合于使用footer元素(FIG 5.01)。

语义化

百分之九十的情况下,你可能在内容的头部使用header元素,在内容的底部使用footer元素,在侧边栏使用aside元素。但是不要迷惑,站住头脚,坚持那剩余的百分之十。

nav

nav元素最贴近你所想象的样子。它通常包含一个用于导航的链接列表。

事实上,我需要向你进行阐清事实。nav元素适用于主要的导航信息。仅仅因为一组链接列表的组合不足以使用nav元素。另一方面,仅仅立足于导航内容,那么几乎所有的内容都可以使用nav元素。

很多时候,nav元素常出现在header元素中。当你认为header元素被用于导航条目时,这是有道理的。

article

想到将header,footer,nav,aside元素指定为section的组成部分是十分有帮助的。section元素被认为是相关内容的通用块,而header,footer,nav,aside是特定种类的相关内容块。

article元素是另外一种特殊类型的section。常被用来自包含内容。最先最棘手的问题是什么是“自包含(self-contained)”。

询问自己是否愿意以RSS或者Atom的提要形式摘要内容。如果这种情况内容依旧有意义,那么article元素很可能就是正确的使用元素。事实上,article元素就是专门为摘要设计的。

如果你在article内使用time元素,你可以选择使用pubdate布尔属性表明它包含的出版日期:

<article>
    <header>
        <h1>DOM Scripting review</h1>
    </header>
    <p>A small lighthouse for what has been a long  and sometimes dark voyage for JavaScript.</p>
    <footer>
        <p>Published
            <time datetime="2005-10-08T15:13" pubdate>
                3:13pm on October 8th, 2005
            </time>
            by Glenn Jones
        </p>
    </footer>
</article>

如果你在一个article内使用多个time元素,你只可以使用一个pubdate属性。

article元素适用于博客文章,新闻报道,评论或者论坛帖子等等。它涵盖了hAtom微格式完全相同的用例。

HTML5规范远不止于此。它也声明了article元素适用于自包含的窗口小部件:股票行情,计算器,钟表,天气窗口小部件等。现在article元素涵盖微软网页快讯的所有用例。

我的直观理解是article元素应该被应用到被称为“小部件”的构建之中。话又说回来,无论是article还是部件都是可包含摘要类型的内容。

重要的问题是articlesection元素十分相似。唯一的区分点在于是否自包含。如果有一些硬性规定,那么决定使用哪种元素就会变得十分简单。所以这就是问题的突破口。你可以在一个article中使用多个section元素,也可以你也可以在一个section中使用多个article,你也可以嵌套使用section或者article。这取决于给定的情况下使用哪种元素更具有语义化。

取代 div?

HTML5给我们提供的元素屈指可数,如上所述。如果你在构建一个传统的网站,例如博客,使用他们就会变得十分方便。大多数的博客设计由一个头部,紧接着是一系列文章,侧边栏内容以及一个页脚组成。如下所示:

语义化

现在你可以使用一些更精准的语义结构元素来替换之前使用的div元素。但是不要过度使用,如果你现在使用的某些div,以后也将继续使用。不要仅仅是因为新鲜而去替换你原先的div元素。要记得去考虑它的内容构造。

这些新元素的创造不仅仅用来取代div元素,它们的产生是为了浏览器更好地去解析你的内容。

内容模型

以前的标记元素分为两类:行内元素和块元素。HTML5提供了更为精准的分类。

内联元素现在被称为“文本级语义”的内容模型。许多块元素被“内容分组”所取代,如:段落,列表项,div等等。表单有自己独立的内容模型。图片、音频、视频以及画布被称为“嵌入式内容”。新的结构元素被称为一种全新的内容模型--“区域内容”。

区域内容

它可以使用标题元素h1~h6创建HTML文档的一个大纲。例如,如下示例的结构标记:

<h1>An Event Apart</h1>
<h2>Cities</h2>
<p>Join us in these cities in 2010.</p>
<h3>Seattle</h3>
<p>Follow the yellow brick road to the emerald city.</p>
<h3>Boston</h3>
<p>That's Beantown to its friends.</p>
<h3>Minneapolis</h3>
<p>It's so <em>nice</em>.</p>
<small>Accommodation not provided.</small>

这个示例提供给我们的大纲如下:

语义化

这种方式看起来很好。标题元素下面的任何内容都假定与此标题相关。

让我们看一下最后的small元素。它应该与整个文档相关。但是浏览器无法解析。这里无法判断small元素是不是隶属于“Minneapolis.”。

HTML5的区域内容可以让你从头到尾很明确的划分相关的内容。

<h1>An Event Apart</h1>
<section>
    <header>
        <h2>Cities</h2>
    </header>
    <p>Join us in these cities in 2010.</p>
    <h3>Seattle</h3>
    <p>Follow the yellow brick road.</p>
    <h3>Boston</h3>
    <p>That's Beantown to its friends.</p>
    <h3>Minneapolis</h3>
    <p>It's so <em>nice</em>.</p>
</section>
<small>Accommodation not provided.</small>

现在可以很明显的看出small元素隶属于标题“An Event Apart” 而不是

现在可以很明显的看出small元素隶属于标题“An Event Apart” 而不是“Minneapolis.”。

我甚至可以进一步细化此内容,将每一个城市放置在自己的section元素之中:

<h1>An Event Apart</h1>
<section>
    <header>
        <h2>Cities</h2>
    </header>
    <p>Join us in these cities in 2010.</p>
    <section>
        <header>
            <h3>Seattle</h3>
        </header>
        <p>Follow the yellow brick road.</p>
    </section>
    <section>
        <header>
            <h3>Boston</h3>
        </header>
        <p>That's Beantown to its friends.</p>
    </section>
    <section>
        <header>
            <h3>Minneapolis</h3>
        </header>
        <p>It's so <em>nice</em>.</p>
    </section>
</section>
<small>Accommodation not provided.</small>

最后得到的大纲是一致的:

语义化

大纲算法

目前为止,与之前的HTML版本相比,新出现的区域内容并没有给我们提供很多功能。这里有一个小秘密:在HTML5之中,每一个区域内容都有其自己独立的自包含大纲。这就意味着你无需再继续跟踪一开始你使用的标题元素:

<h1>An Event Apart</h1>
<section>
    <header>
        <h1>Cities</h1>
    </header>
    <p>Join us in these cities in 2010.</p>
    <section>
        <header>
            <h1>Seattle</h1>
        </header>
        <p>Follow the yellow brick road.</p>
    </section>
    <section>
        <header>
            <h1>Boston</h1>
        </header>
        <p>That’s Beantown to its friends.</p>
    </section>
    <section>
        <header>
            <h1>Minneapolis</h1>
        </header>
        <p>It's so <em>nice</em>.</p>
    </section>
</section>
<small>Accommodation not provided.</small>

在之前的HTML版本中,这会产生错误的大纲,如下所示:

语义化

HTML5中产生的大纲是准确的,如下所示:

语义化

hgroup

可能存在这种情况,你想要使用多个标题元素,但是你不想要其内容出现在不同的大纲之中。这时hgroup元素就可以很好的满足你的需求。

<hgroup>
    <h1>An Event Apart</h1>
    <h2>For people who make websites</h2>
</hgroup>

在这种情况下,二级标题内容“For people who make websites”仅仅是一个口号而已。在hgroup元素中,只有第一标题才是大纲的组成部分。当然,这里的第一标题不仅限于h1:

<hgroup>
    <h3>DOM Scripting</h3>
    <h4>Web Design with JavaScript and the Document Object Model</h4>
</hgroup>

根区域

存在一些元素在大纲中是不可见的,换句话说,不管你是要多少多少此类元素,他们都不会出现在你的大纲之中。

blockquotefieldset以及td元素对大纲算法都是免疫的。这些元素被称为"区域根"--不要与区域内容相混淆。

可移植性

由于每一个区域内容都可以生成自己的大纲,你现在得到的标题级别就不仅仅局限于h1~h6。这里你的标题级别就不存在限制了。更重要的是,你可以开始考虑以一种模式化的方式创建内容。

假设这里有一个名为“Cheese sandwich.”的博客。在HTML5之前我需要考虑博客的背景决定如何使用标题元素,如果是该信息位于页眉那么就使用h1以下的标题对博客进行标注。

<h1>My awesome blog</h1>
<h2><a href="cheese.html">Cheese sandwich</a></h2>
<p>My cat ate a cheese sandwich.</p>

但是如果我在自己的网页中发布了此博客,那么此时的博客标题应该使用一级标题:

<h1>Cheese sandwich</h1>
<p>My cat ate a cheese sandwich.</p>

在HTML5中,我并不需要担心标题的使用。在这个示例中,我仅仅需要使用区域元素--article:

<article>
    <h1>Cheese sandwich</h1>
    <p>My cat ate a cheese sandwich.</p>
</article>

现在内容真的更为便携。不管他出现在页眉或者页脚位置都变得无关紧要:

<h1>My awesome blog</h1>
<article>
    <h1>Cheese sandwich</h1>
    <p>My cat ate a cheese sandwich.</p>
</article>

HTML5的大纲算法产生的大纲如下:

语义化

样式域

每一种区域内容都有其自己独立的大纲,这一事实使它可以与Ajax完美结合使用。强调,这句话出于Web应用程序规范。

试图将一个内容由一个文档转移到另一个之中会出现许多问题。父元素中的CSS规则也会被应用到插入的内容之中。这是目前在网络上散播一些小部件的挑战之一。

HTML5提供了scoped属性来解决此类问题,这可以被应用到样式之中。在此属性中的所有样式仅仅适用于其包含的区域内容:

<h1>My awesome blog</h1>
<article>
    <style scoped>
        h1 { font-size: 75% }
    </style>
    <h1>Cheese sandwich</h1>
    <p>My cat ate a cheese sandwich.</p>
</article>

在这个示例中,只有第二个h1元素具有font-size: 75%;样式。当然这仅仅在理论上讲得通,目前还没有得到任何一种浏览器的支持。

总结

文章介绍了HTML5的一些自带义语义化的标签,对于语义化争议还是非常的大,但如果你的HTML结构写得更具语义化,还是有足多的好处,比如你团队的成员更易读懂你的代码。当然还有很多同学担心这些标签浏览器对他的支持力度如何?其实很多HTML5标签都已运用到实际项目中。

如果你对这方面有更深的理解,欢迎在下面的评论中与我们一起分享你的见解。

本文根据@JEREMY KEITH的《HTML5 For Web Designers:Semantics》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://html5forwebdesigners.com/semantics/

静子

在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶

如需转载,烦请注明出处:http://www.w3cplus.com/html5/semantics-tags.html

返回顶部