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
等元素。奥~ 现在我们不称之为内联元素了,取而代之,他们现在是“文本级语义”。
在浏览搜索的结果列表中,你会经常看到每一个搜索结果中会突出显示搜索词。你可以使用 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
元素也可以在非搜索环境中使用,但是我还没有想到一个很好的使用环境。
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>9 out of 10 cats</meter>
如果你不想暴露最大值,你可以使用 max
属性代之。
<meter max="10">9 cats</meter>
相应的还有一个 min
属性。同时你也可以使用 high
, low
和 optimum
属性。如果你愿意,你甚至可以使用 value
属性隐藏隐藏其自身的测量值。
<meter low="-273" high="100" min="12" max="30" optimum="21" value="25"> It's quite warm for this time of year. </meter>
你可以使用 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
元素用于组合一些主题相关的内容。这听起来很像用作通用容器的 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>
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
的头部,但是这并不是必须的。它是由介绍的内容以及是否具有导航作用来决定的,而不是其位置决定的。
类似于 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>
像 header
元素匹配报头部分, aside
元素匹配侧边栏部分。但是,这里我所提及的 aside
与位置无关。仅仅因为一些内容出现在主内容的左边或者右边不足以使用 aside
元素。再次强调,它与内容相关,与位置无关。
aside
元素应该被用于无关内容。如果你有你认为应该与主内容分开的内容,那么 aside
元素是你应该正确考虑使用的元素。询问你自己 aside
元素中的内容是否可以被独立开来而不会影响文档或者 section
中主内容的含义。
Pullquotes是关于无关内容的一个很好例子。这部分内容的存在是很好的,但你也可以删除它们而不会影响对主要内容的理解。
请记住,仅仅因为你的视觉设计需要一些内容在侧边栏出现并不一定意味着 aside
元素是正确的包含元素。 例如,侧边栏部分出现一个作者的介绍是很常见的。 类似于这种数据使用 footer
元素是最适合的--规范明确提到作者的信息适合于使用 footer
元素(FIG 5.01)。
百分之九十的情况下,你可能在内容的头部使用 header
元素,在内容的底部使用 footer
元素,在侧边栏使用 aside
元素。但是不要迷惑,站住头脚,坚持那剩余的百分之十。
nav
元素最贴近你所想象的样子。它通常包含一个用于导航的链接列表。
事实上,我需要向你进行阐清事实。 nav
元素适用于主要的导航信息。仅仅因为一组链接列表的组合不足以使用 nav
元素。另一方面,仅仅立足于导航内容,那么几乎所有的内容都可以使用 nav
元素。
很多时候, nav
元素常出现在 header
元素中。当你认为 header
元素被用于导航条目时,这是有道理的。
想到将 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
还是部件都是可包含摘要类型的内容。
重要的问题是 article
和 section
元素十分相似。唯一的区分点在于是否自包含。如果有一些硬性规定,那么决定使用哪种元素就会变得十分简单。所以这就是问题的突破口。你可以在一个 article
中使用多个 section
元素,也可以你也可以在一个 section
中使用多个 article
,你也可以嵌套使用 section
或者 article
。这取决于给定的情况下使用哪种元素更具有语义化。
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> <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>
存在一些元素在大纲中是不可见的,换句话说,不管你是要多少多少此类元素,他们都不会出现在你的大纲之中。
blockquote
、 fieldset
以及 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/ 。
在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶