语义化 HTML
使用能清晰传达内容含义和结构的 HTML 元素。正确使用 header、nav、main、article、section 等元素。
语义化 HTML 是指恰当使用能够清晰传达内容含义和结构的 HTML 元素。<div> 和 <span> 是通用容器元素,本身没有语义。而 <header>、<nav>、<main>、<article>、<section>、<aside>、<footer> 等语义元素则明确表示了所包含内容的角色。借助 HTML5 引入的这些元素,仅通过标记就能准确表达页面的结构。
关于 SEO 效果存在着广泛的误解。Google 搜索中心的 SEO 入门指南完全没有提到 <article> 或 <section> 这类语义元素,关于标题则明确写道"从 Google 搜索的角度看,即使没有按顺序使用也没有问题",并把这个话题归入"不必投入精力的事项"。给出的理由之一是,从整个 web 来看,HTML 写得不够规范的页面很多,因此无法完全依赖 HTML 规范所寄托的语义。因此,"换成语义元素就能提升排名"这样的因果关系并没有得到官方的证实。想向搜索引擎明示结构时,正统的做法是结构化数据 (JSON-LD),它可以成为丰富结果的对象。把语义化 HTML 的投入产出理解为在无障碍与可维护性这一侧,而不是在排名一侧,更符合实际情况。
在无障碍方面,屏幕阅读器会把语义元素识别为地标 (路标),使用户能够高效地在页面内移动。macOS 的 VoiceOver 具备以地标为单位在页面内移动的功能,可以直接跳转到导航或主要内容这类区域。在仅用 <div> 构建的页面上,无法使用这种移动手段。
不过,被当作地标处理的条件存在陷阱。W3C 的 ARIA in HTML 规定,<header> 成为 banner、<footer> 成为 contentinfo,仅限于它不是 <article>、<aside>、<main>、<nav>、<section> 的后代之时。放在文章卡片内部的 <footer> 会被当作 generic (不具语义的元素) 处理,不会成为地标。<section> 的条件更为严格,如果没有可访问名称 (通过 aria-label 或 aria-labelledby 赋予的、相当于标题的名称),它就不会成为 region 地标,没有名称的 <section> 无论排列多少个都不会出现在地标列表中。以为把 <div> 机械地替换成 <section> 就能传达给辅助技术,是常见的错误。
标题元素 (<h1> 到 <h6>) 恰当的层级结构也是语义化 HTML 的重要组成部分。不跳过标题级别 (h1 之后不使用 h3),按逻辑顺序使用,文档结构就会变得清晰。屏幕阅读器的用户会从标题列表跳转到目标位置,因此标题层级一旦混乱,访问信息就会变得困难。这里重要的是不要弄错依据。HTML 规范中并没有禁止跳级的规定,如前所述 Google 也表示不追究顺序。即便如此,整理层级仍然有价值,原因在于标题的嵌套会作为目录被辅助技术直接读出,成为读者把握全貌的线索。
一个常见的误解是"使用语义元素会限制 CSS 的样式设置"。实际上,语义元素可以像 <div> 一样用 CSS 自由地设置样式,在外观上没有限制。此外,也有人在 <section> 与 <article> 的区分上犹豫,而判断基准由 HTML 规范提供。<article> 被定义为"原则上可以单独分发或再利用的、完整的构成物",博客文章、新闻报道、投稿、评论这类切出来仍然讲得通的内容属于此列。关于 <section>,规范明言它"不是通用的容器元素",只有在其内容会作为条目排入文档大纲 (目录) 时才算恰当。反过来,如果只是出于样式或脚本的需要想要包起来,规范上推荐使用 <div>。事先定下"无法为其加上标题的整块内容就不做成 <section>",判断就会稳定下来。
从字符计数的角度看,语义元素的标签名会比 div (3 个字符) 更长 (article 和 section 都是 7 个字符)。按开始标签与结束标签成对来数,<div></div> 是 11 个字符,<article></article> 是 19 个字符,每个元素相差 8 个字符。即使有几十个元素,增加的也只有几百个字符,能够准确传达语义的好处更胜一筹。由于不影响文本内容的字符数,用户看到的字符数以及粘贴到字符计数器后的结果都不会改变。