堂主 - WEB前端开发

专注于互联网 | WEB前端开发 | 以用户为中心的体验 | 家是圆心 | Code is art !

HTML5 大纲算法(HTML5 Outliner)

Tags : HTML5   语义   重构   译文     1 comments

堂主原创博文,转载请加本页链接,谢谢合作:

http://www.osmn00.com/rebuild/223.html

-------------------------------- 分割线 ----------------------------------

HTML大纲算法

HTML中存在着一个大纲算法,大纲可以为用户提供同一份页面的信息结构目录,就像之前我们在word和pdf文档中体验过的那样。

PDF文档中的目录结构:

pdf.gif

没有HTML5之前

HTML5之前的HTML4,唯一的方式是采用<h1> ~ <h6>元素来创建大纲。因为正常习惯下,<h1> ~ <h6>表示了从第一级到第六级的层级递减标题,而标题之下就应该是对应的内容了。

合理正确的使用标题元素可以为文档赋予一个良好结构的大纲,不单单对于搜索引擎的优化,更是为借助于屏幕阅读器浏览器网页的盲人(或弱视力)用户提供了巨大的帮助。

在非采用HTML5对网页进行重构的情况下,合理正确的使用标题元素依然可以为文档赋予一个良好结构的大纲,比如目前堂主博客的首页模板:

gg-测试插件.png

这个首页采用了如下的结构:

<body>
<h1>堂主 - WEB前端开发</h1>

<h2>博客导航</h2>
<ul>...</ul>

<h2>文章列表</h2>
  <ol>
    <li><h3>...</h3></li>
  </ol>

<h2>边栏应用标题...</h2>
  ...

</body>

现实不总是那么美好

但在某些情况下,比如一个标题下还需要一个副标题;或者网站本身是聚合性质的,内容都是以模块的形式从其他网站摘取、嵌入、拼合而成。那么这种情况下,原有技术基础上的大纲算法会提供一个灾难性的大纲目录。

比如我为我的博客名称添加一个副标题(或者在其他情景的时候会为一篇文章添加一个副标题;或者像现在流行的团购网站那样,在网站LOGO+名称的下面都会来上一句口号),就像我们经常在WordPress中做的那样:

wordpress中设置副标题.png

OK,我为我的博客增加了一个副标题,结构代码可能会变成下面这样:

<body>
<h1>堂主 - WEB前端开发</h1>
<h2>Code is art!</h2>
...

</body>

此时页面大纲会变成下面的样子:

添加副标题后的大纲.png

我这里只是增加了一个博客副标题,结果大纲目录中新增加出来一个标号为1的二级“Code is art !”标题,这会弄得屏幕阅读器用户晕头转向:因为这只是博客名称的副标题,而不是某块内容区域的实用性指向标题。无奈的替换办法一般是将这个副标题放入<p></p>中,并设置<p class="subheading">来对段落中的内容进行说明。但这么做是在损害我们代码的语义性,因为这部分文字毕竟是一个标题而不是一段简单的内容文字。

试想如果一个网页是聚合类网页,里面呈现很多条从信息源网站摘取来的文章块(包括该文章的标题和简述),如果不同信息源的文章标题使用的元素还不一致(有的是<h1>有的可能是根据自身页面上下文采用其他等级的H),那么该聚合网页的大纲会是多么的魔鬼!盲人用户会不会高呼“杀了我!”?

新技术带来的解脱

于是新的HTML5中定义了一个非常严谨的大纲算法,并且对语义性内容布局元素赋予了一个“开始新的节”的功能。个人理解,HTML5中,元素在大纲中的表现可以简单分为以下三类:

  • 无作为
  • 开始一个新的节
  • 成节的根

无作为

“无作为”是我个人对这类元素的称呼,它们在页面大纲中不会产生新的节。如下面的这段代码:

<div>这是一个没有语义的层</div>
<ul>
  <li>一个无序列表</li>
</ul>

 在浏览器的“HTML5 Outliner”插件中(本文末尾会介绍2款浏览器中使用的插件)查看会如下呈现:

无作为的.png

大纲中没有子节,只有一个无标题的body根。

开始一个新的节

而像<article>、<section>、<nav>、<aside>等新的语义性元素,会开始一个新的节,如下代码:

<body>
<section>这是页面中的一个主题区域</section>
<aside>这是页面中的一个边栏区域</aside>
</body>

 在浏览器的“HTML5 Outliner”插件中查看会如下呈现:

开始一个新的节.png

另外已有的<h1> ~ <h6> 也会创建新的节,但H元素在创建新的节的时候会遵循一个出现的顺序的问题,如下两段不同代码演示的:

<body>
  <h1>H1</h1>
  <h2>H2</h2>
  <h3>H3</h3>
  <h4>H4</h4>
  <h5>H5</h5>
  <h6>H6</h6>
  
  <h6>H6</h6>
  <h5>H5</h5>
  <h4>H4</h4>
  <h3>H3</h3>
  <h2>H2</h2>
  <h1>H1</h1>
</body>

 H顺序和倒序.png

同一节中,H元素会依照自身大小创建新的节和归属不同级别。如果我们改一下倒序列中的<h6>为<h3>

<body>
  <h1>H1</h1>
  <h2>H2</h2>
  <h3>H3</h3>
  <h4>H4</h4>
  <h5>H5</h5>
  <h6>H6</h6>
  
  <h3>H3</h3>
  <h5>H5</h5>
  <h4>H4</h4>
  <h3>H3</h3>
  <h2>H2</h2>
  <h1>H1</h1>
</body>

 那么其的大纲会变为下面的样子:

改了顺序的H.png

背后的逻辑是:出现在最前面的<h1>创建了一个新的节,其后的所有小于它的H元素都在其创建的节内再创建子节。一个节内,同重的H元素在大纲中会出现在相同的级中。所以后面倒序的H元素会像上面截图中那样呈现。

成节的根

《HTML5用户指南》中这样介绍这类元素:

某些元素(<blockquote>、<body>、<details>、<fieldset>、<figure>、<td>)叫做成节的跟,并且它们可以拥有自己的大纲。但是,这些元素中的节和标题对于它们的祖先的大纲没有任何影响。

 简单的说,在<body>里,如果你使用了<blockquote>等,即时它们自身包含的内容中有用于创建新的节的元素(<h2>或者一个<nav>),但在针对body这个根的大纲里,这些也都不会显示。如下代码:

<body>
  <h1>H1</h1>
  <section>
    <h2>您吃了么?</h2>
  </section>
  
  <blockquote>
    <section>
      <h2>今天星期几?</h2>
    </section>
  </blockquote>
  
  <section>
    <h2>吃了!</h2>
  </section>
</body>

 成节的根.png

很明显,虽然<blockquote>里包含了<section>和<h2>,但在大纲中并无显示。

小工具

对于大纲的可视化,这里介绍2款浏览器中应用的插件。《HTML5用户指南》《HTML5揭秘》中都给出了一个在线测试查看的网址,不过我这里测试都是网页测试程序存在问题。还好我们有更方便的替代方案——浏览器插件。

Opera平台上的插件

Opera的这款HTML5 Outliner插件需要安装Opera 11及以上版本的浏览器。浏览器下载地址可以去官网下载,插件地址在这里:https://addons.opera.com/addons/extensions/details/html5-outliner/1.0/?display=en

 op-安装插件.png

安装完成后打开浏览器,会在右上角出现一个HTML5 Outliner的按钮:

op-按钮位置.png

打开要查看的网站,点击这个按钮就OK了:

op-测试插件.png

Chrome下的插件

同样,扩展搜索中搜索:HTML5 Outliner

gg-搜索插件.png

安装:

gg-安装插件.png

安装完之后默认在浏览器上不会出现变化,但在访问某个网址的时候,会在地址栏右侧,“书签”按钮的左侧显示出“HTML5 Outliner”的按钮:

gg-按钮位置.png

使用方法同样,网页加载完毕后点击这个按钮:

gg-测试插件.png

后记

堂主写这篇博客的时候尚不清楚目前浏览器对HTML5的大纲算法支持程度究竟怎样,手头的资料显示的是尚无一款能完整支持的浏览器。这意味着目前的屏幕阅读器用户可能不会很快体验到新技术带来的便利。这就要求我们在编写页面的时候最好遵循文档中节的套嵌层级使用相应的H元素,保证标题的层级正确。避免所有层级都只用<h1>——即使这么做在新的HTML5中是属于容许范围的。

 

参与讨论

*

*