Web 语义化是指使用恰当语义的 html 标签元素、class 类名、属性、和属性值(包括像Microdata之类的扩展)等内容,让页面具有良好的结构与含义,从而让人和机器都能快速理解网页内容。语义化的 web 页面一方面可以让机器在更少的人类干预情况下收集并研究网页的信息,从而可以读懂网页的内容,然后将收集汇总的信息进行分析,结果为人类所用;另一方面它可以让开发人员读懂结构和用户以及屏幕阅读器(如果访客有视障)能够读懂内容。简单来说就是利于 SEO,便于阅读维护理解。

总结起来就是:

  • 正确的标签做正确的事情
  • 页面内容结构化
  • 无 CSS 样子时也容易阅读,便于阅读维护和理解
  • 便于浏览器、搜索引擎解析。 利于爬虫标记、利于 SEO

为什么要语义化?

  • 有利于 SEO 。

SEO 也就是 Search Engine Optimization,搜索引擎优化。指通过站内优化比如网站结构调整、网站内容建设、网站代码优化等以及站外优化,比如网站站外推广、网站品牌建设等,使网站满足搜索引擎收录排名需求,在搜索引擎中提高关键词排名,从而吸引精准用户进入网站,获得免费流量,产生直接销售或品牌推广。

人可以通过视觉的划分判断内容的语义,而搜索引擎只能通过爬取网页标签等代码来判断内容的语义。得到搜索引擎的有效爬取,是提高网站流量的有效方法之一。要使页面尽可能地对搜索引擎友好,所以就要尽可能地使标签和内容语义化。

  • 在页面去掉或样式丢失的时候,能让页面呈现清晰的结构。html 的一些标签,例如 h1(粗体)、 strong(加粗)、em(斜体),通过一些默认的样式,可以使页面即使在缺失 CSS 样式修饰时也能呈现清晰的结构。
  • 屏幕阅读器(如果访客有视障)会完全根据你的标记来 “读” 你的网页,便于无障碍阅读。
  • 团队开发中,良好的语义化标签,可以减少很多差异化,减少成员间沟通成本,方便开发和后期维护,利于实现模块化开发。

Web 语义化的分类

Web 语义化应该是样式与结构分离的结果,重构中的语义化包含 HTML 标签语义化和 CSS 命名语义化,HTTP 的语义化是针对 HTTP 协议来说。

HTML 标签语义化

HTML 为网页文档内容提供上下文结构和含义。对于 HTML 体系而言,Web 语义化是指使用语义恰当的标签,使页面有良好的结构,让页面元素有含义,便于被浏览器、搜索引擎解析。通常我们所说的 HTML 应该是完全脱离表现信息的,其中的标签应该都是语义化地定义了文档的结构。

例如:

为了 SEO,我们会选择 h1 标签来突出标题,用 strong 标签来突出关键字,这其实就是语义化的体现。SEO 的原理其实是分析源码来体现或猜测网站要表达的内容。比如我们想表达某篇文章的标题, 我们或许会这样写:

<div class="title">文章的标题</div>

但是为了更好的讨好搜索引擎我们最好写成如下形式:

<h1>文章的标题</h1>

根据应用场景,一些常用的标签元素有:

  • 本身无实在意义,组合其他 HTML 元素,常用于页面布局: div
  • 设置文本,填充段落: h1~h6, p, span, strong, em…
  • 表现列表:ul, li, ol, dl, dt, dd
  • 表单相关:form,input,select,button
  • 表格相关:table,thead,tbody,tfoot,th,tr,td
  • 用于图像显示:img, canvas
  • 打开链接,发送邮件,段落跳转:a

此外,meta Description/meta keywords 等针对搜索引擎和更新频度的描述和关键词的 meta 标签也会用来实现网页的 SEO。

HTML 规范其实一直在往语义化的方向上努力,许多元素、属性在设计的时候,就已经考虑了如何让各种用户代理甚至网络爬虫更好地理解 HTML 文档。

HTML5 更是在之前规范的基础上,将所有表现层的语义描述都进行了修改或者删除,增加了不少可以表达更丰富语义的元素,也出现很多可以替代 div 元素的更具象的标签。

一个经典的页面结构如图:

header 元素

header 代表 “网页” 或者 “section” 的页眉,通常包含 h1-h6 元素或者 hgroup, 作为整个页面或者一个内容快的标题。也可以包裹一节的目录部分,一个搜索框,一个 nav,或者相关 logo。

代码示例:

<header>
  <hgroup>
    <h1>标题</h1>
    <h2>副标题</h2>
  </hgroup>
</header>

注意事项:

  1. 可以是 “网页” 或者任意 “section” 的头部部分
  2. 没有个数限制
  3. 如果 hgroup 或者 h1-h6 自己就能工作得很好,那么就没必要用 header。

hgroup 元素

hgroup 元素代表 “网页” 或“section”的标题,当元素有多个层级时,该元素可以将h1h6元素放在其内,譬如文章的主标题和副标题组合

代码示例:

<hgroup>
    <h1>这是一个主标题</h1>
    <h2>这是一个副标题</h2>
</hgroup>

注意事项:

  1. 如果只需要一个 h1-h6 标签就不用 hgroup
  2. 如果有连续多个 h1-h6 标签就用 hgroup
  3. 如果有连续多个标题和其他文章数据,h1-h6 标签就用 hgroup 包住,和其他文章元数据一起放入 header 标签

footer 元素

footer元素代表 “网页” 或任意 “section” 的页脚,通常含有该节的一些基本信息,譬如:作者,相关文档链接,版权资料。如果footer元素包含了整个节,那么它们就代表附录,索引,提拔,许可协议,标签,类别等一些其他类似信息。

代码示例:

<footer>
    Slogan
    COPYRGHT
</footer>

注意事项:

  1. 可以是 “网页” 或者任意 “section” 的底部部分
  2. 没有个数限制,除了包裹的内容不一样,其他跟 header 类似

navigation 元素

nav 元素代表页面的导航链接区域。用于定义页面的主要导航部分。

代码示例:

<nav>
  <ul>
    <li><a href="#">主页</a></li>
    <li><a href="#">关于我们</a></li>
  </ul>
</nav>

侧边栏上目录、面包屑导航、搜索样式、或者下一篇上一篇文章我们可能会想要用到 nav,但是事实上规范上说 nav 只能用在页面主要导航部分上。页脚区域中的链接列表,虽然指向不同网站的不同区域,譬如服务条款,版权页等,这些 footer 元素就能够用了。

注意事项:

  1. 用于整个页面的主要导航部分,不适合就不要用 nav 元素了

article 元素

article 代表一个在文档,页面或者网站中自成一体的内容,其目的是为了让开发者独立开发或重用。

除了它的内容,article 会有一个标题 (通常会在header里),一个footer页脚。

代码示例:

<article>
  <h1>你好,我是这边文章的标题</h1>
  <p>你好,我是文章的内容</p>
   <footer>
     <p>最终解释权归XXX所有</p>
  </footer>
</article>

这是一个最简单的例子,如果在 article 内部再嵌套 article,那就代表内嵌的 article 是与它外部的内容有关联的,如博客文章下面的评论,如下:

   <article>

       <header>
           <h1>web 语义化</h1>
           <p><time pubdate datetime="2018-03-23">2018-03-23</time></p>
       </header>

       <p>文章内容..</p>

       <article>
           <h2>评论</h2>

           <article>
               <header>
                   <h3>评论者: 专业水军</h3>
                   <p><time pubdate datetime="2018-03-23T15:10-08:00">~1 min ago</time></p>
               </header>
               <p>还行</p>
           </article>

           <article>
               <header>
                   <h3>评论者: 大水怪</h3>
                   <p><time pubdate datetime="2018-03-23T15:10-08:00">~1 hour ago</time></p>
               </header>
               <p>楼上说的对</p>
           </article>

       </article>

   </article>

article 内部可以嵌套 article,表示评论或者其他跟文章有关联的内容。article 内部还可以嵌套 section,如下:

   <article>

       <h1>web语义化</h1>
       <p>什么是语义化?</p>

       <section>
           <h2>语义化详解</h2>
           <p>语义化就是。。。</p>
       </section>

       <section>
           <h2>语义化特点</h2>
           <p>语义化特点就是。。。</p>
       </section>

   </article>

文章内 section 是独立的部分,但是它们只能算是组成整体的一部分,从属关系,article 是大主体,section 是构成这个大主体的一个部分。

注意事项:

  1. 自身独立情况下:用 article
  2. 是相关内容: 用 section
  3. 没有语义的: 用 div

    section 元素

section 元素代表文档中的 “节” 或“段”,“段”可以是指一片文章里按照主题的分段;“节”可以是指一个页面里的分组。section通常还带标题,虽然 html5 中 section 会自动给标题 h1-h6 降级,但是最好手动给他们降级。

代码示例:

   <section>
       <h1>section是啥?</h1>
       <article>
           <h2>关于section</h2>
           <p>section的介绍</p>
           <section>
               <h3>关于其他</h3>
               <p>关于其他section的介绍</p>
           </section>
       </article>
   </section>

注意事项:

  1. 一张页面可以用 section 划分为简介、文章条目和联系信息。不过在文章内页,最好用 article。section 不是一般意义上的容器元素,如果想作为样式展示和脚本的便利,可以用 div。
  2. 表示文档中的节或者段。
  3. acticle、nav、aside 可以理解为特殊的 section,如果可以用 article、nav、aside 就不要用 section,没有实际意义的就用 div

figure 标记

包含图像、图表和照片。figure 标记可以包含 figcaption,figcaption 表示图像对应的描述文字,与图片产生对应关系。

<figure>
  <img src="/figure.jpg" width="304" height="228" alt="Picture">
  <figcaption>Caption for the figure</figcaption>
</figure>

媒体元素

一些常用的媒体元素包含:audio / video / source / embed

<audio id="audioPlay">
   <source src="../h5/music/act/iphonewx/shakeshake.mp3" type="audio/mpeg">
   您的浏览器不支持 audio 标签。
</audio>

#### aside 元素

aside 元素被包含在article元素中作为主要内容的附属信息部分,其中的内容可以是与当前文章有关的相关资料,标签,名词解释等。
article元素之外使用作为页面或站点全局的附属信息部分。最典型的是侧边栏,其中的内容可以是日志串连,其他组的导航,甚至广告,这些内容相关的页面。

代码示例:

   <article>
       <p>内容</p>
       <aside>
           <h1>作者简介</h1>
           <p>哈哈哈</p>
       </aside>
   </article>

注意事项:

  1. aside 在 article 内表示主要内容的附属信息。
  2. 在 article 之外侧可以做侧边栏,没有 article 与之对应,最好不用
  3. 如果是广告,其他日志链接或者其他分类导航也可以用。

    html 语义化小结

总之,HTML 语义化是反对大篇幅使用无语义化的 div+span+class,而鼓励使用 HTML 定义好的语义化标签。

当然,如果需要兼容低版本的 IE 浏览器,比如说 IE8 以及以下,那就需要考虑一些 HTML5 标签兼容性解决方案了。
更多标签及其兼容性请去往传送门
html5 标签列表传送门

### CSS 语义化

CSS 语义就是 class 和 id 命名的语义。class 属性作为 HTML 与 CSS 衔接的纽带,其本意是用来描述元素内容的。指用易于理解的名称对 html 标签附加的 class 或 id 命名。如果说 HTML 语义化标签是给机器看的,那么 CSS 命名的语义化就是给人看的。良好的 CSS 命名方式减少沟通调试成本,易于理解。

CSS 命名首先要满足 W3C 的命名规范和团队的命名规范。其次是高效和可重用性。

就好像. main/.sidebar 会比. left_content/.right_content 的 class 命名灵活性更好。

<!-- 以表现为中心 -->
<div class="ft margin10">
   <span>nickName:seg</span>
<div>

<!-- 以信息为中心 -->
<p class="user_info">
   <em>nickName:seg</em>
<p>

看到这里,问题来了。既然 CSS class 和 id 命名的语义化可以便于阅读理解和减少沟通调试成本,那么我们是不是可以用 div 结合 class 和 id 语义化命名的方式来代替 html 的语义化?

代码示例:

   <html>
       <body>
           <div class="article">
               <div class="header">
                   <h1>h1 - WEB 语义化</h1>
               </div>
               <div class="nav">
                   <ul>
                       <li>nav1 - HTML语义化</li>
                       <li>nav2 - CSS语义化</li>
                   </ul>
               </div>
               <div class="section">
                   section1 - HTML语义化
               </div>
               <div class="section">
                   section2 - CSS语义化
               </div>
               <div class="time">time - 2018年03月23日</div>
               <div class="footer"> footer content </div>
           </div>
       </body>
   </html>

从代码的层面上来看,使用 CSS class 语义化的命名也是能够便于阅读和维护的,但是这样子并不利于 SEO 和屏幕阅读器识别。

URL 语义化

url 语义化,可以使得搜索引擎或者爬虫更好地理解当前 url 所在目录所需要表达的内容;而对于用户来说,通过url 也可以判断上一级目录或者下一级目录想要表示的内容,可以提高用户体验。

例如我司的搜索品类的 url:

https://mall.midea.com/index.php/category?id=10049&addr_code=440000,440100,440103
https://mall.midea.com/category?id=10049&addr_code=440000,440100,440103

这两个 url 指向的是同一个资源,但是显然第二个 url 对于用户和搜索引擎更加友好。

url 语义化可以从以下标准来衡量:

  1. url 简化,规范化:url 里的名词如果包含两个单词,那么就用下划线_ 连接。
  2. 结构化,语义化:此处的品类搜索我们用语义化单词 category 表示
  3. 采用技术无关的 url:第一个链接中的 index.php 这种就不应该出现在用户侧的 url 里。

ARIA 无障碍 Web 规范

ARIA 即 Accessible Rich Internet Application,中文译为无障碍富互联网应用。可以为一些有功能障碍(如听力,视力)的人群通过屏幕阅读器例如 voiceover 等,提供无障碍访问动态、可交互 Web 内容。

而应用于 HTML 的 ARIA 有两部分组成:role 和 aria-* 。

其中,role 标识了一个元素的作用,aria – 描述了与之有关的事物特征及其状态。

ARIA 的具体使用规则可见 ARIA in HTML

W3C 对 ARIA 无障碍 Web 规范这样解释:

Web developers may use the ARIA role and aria-* attributes on HTML elements, in accordance with the requirements described in [wai-aria-1.1], except where these conflict with the strong native semantics or are equal to the implicit ARIA semantics of a given HTML element.

Setting an ARIA role and/or aria-* attribute that matches the implicit ARIA semantics is unnecessary and is not recommended as these properties are already set by the browser.

所以,如果使用的元素 (HTML5) 本身具有语义化,应该使用这些元素,而不用再重新定义一个添加 ARIA 的角色、状态或属性的元素。

例如:

nav 已经隐含 ARIA 的 role=”navigation” 声明,就不用在