第 28 节 · 语义化与无障碍
第 28 节 · 语义化与无障碍
📌 版本信息:基于 HTML Living Standard / WCAG 2.2 / ARIA 1.2 现行推荐(2026-08-29 核对) 📚 来源:MDN 无障碍 | WAI-ARIA 基础 | MDN SEO 入门
一、这一节的目标(阶段二开始)
- 说出语义化的三层受益者:浏览器、辅助技术、搜索引擎
- 掌握 landmark 地标元素的正确用法
- 掌握图片 alt 与表单 label 的无障碍规范(你早就在写了)
- 认识 ARIA 的定位:HTML 语义不够时的"补充说明"
- 理解语义化对 SEO 的影响
二、语义化为什么重要
一句话:标签的"名字"就是它的含义——选对标签,等于免费获得可访问性、SEO 和可维护性。
<!-- ❌ 火柴盒 soup:全是 div,谁也不知道谁是导航 -->
<div class="top"><div class="logo">…</div></div>
<div class="menu">…</div>
<div class="content">…</div>
<!-- ✅ 语义化:结构自解释 -->
<header>…</header>
<nav>…</nav>
<main>…</main>
<footer>…</footer>
三层受益:
- 屏幕阅读器:能按 landmark 跳转("跳到主导航")、能朗读"这是标题第二级"
- 搜索引擎:
<article><h1>权重高于 div 套 div;无障碍还是排名信号 - 你自己:半年后读
<nav>不用猜;DevTools 里结构清晰
三、landmark 地标元素
<body>
<header> <!-- 页头:logo、站名、全局导航的容器 -->
<nav> <!-- 导航区块(可以有多处:主导航/面包屑) -->
</header>
<main> <!-- 主内容区:全页唯一! -->
<article> <!-- 独立成篇的内容(一篇报道、一张卡片若自成一义) -->
<section> <!-- 主题分组,通常配标题 -->
<h2>…</h2>
</section>
</article>
<aside> <!-- 侧边内容:相关链接、广告 -->
</main>
<footer> <!-- 页脚:版权、备案号 -->
</body>
规范要点:<main> 全页唯一;每个 landmark 最好有可访问名称(<nav aria-label="主导航"> 区分多个 nav);section 不该没有标题。
💡 对应关系(读库源码/写 React 时有用):
<header>≈ role="banner",<nav>≈ role="navigation",<main>≈ role="main"。HTML5 标签自带 role,别再给<nav>手写role="navigation"(冗余)。
四、alt 与 label:你早就在写的无障碍
回顾前几节的规范,现在给出"为什么":
<!-- alt:图片的"文字替身"。写法分级: -->
<img src="chart.png" alt="2026 年地震震级分布柱状图" /> <!-- 信息图:描述内容 -->
<img src="logo.png" alt="GeoLearn 首页" /> <!-- 功能图:描述去哪 -->
<img src="divider.png" alt="" /> <!-- 纯装饰:空 alt(读屏跳过)!
千万别省略属性——省略=读屏会念文件名 -->
<!-- label:每个输入控件都有,且显式绑定 -->
<label for="zoom">缩放级别</label>
<input id="zoom" type="number" />
<!-- 点 label 聚焦控件(交互福利)+ 读屏念出名称(无障碍核心) -->
快速自测法:把页面图片和输入框"读"给自己听(或用读屏模式)——念不出内容的地方就是语义缺失。
五、ARIA:语义不够时的补充
ARIA(Accessible Rich Internet Applications)= 一组 role/aria- 属性,向辅助技术"解释"你的自定义组件。*
<!-- 场景 1:div 做的按钮(HTML 语义用尽时的补救) -->
<div role="button" tabindex="0">放大</div>
<!-- ↑ 其实应该直接用 <button>——ARIA 第一法则:能用原生标签就别用 ARIA -->
<!-- 场景 2:原生标签表达不了的状态 -->
<button aria-expanded="false" aria-controls="menu">图层 ▾</button>
<ul id="menu" hidden>…</ul>
<!-- ↑ 告诉读屏"这个按钮控制一个折叠面板,当前收起" -->
<!-- 场景 3:动态通知(地图加载完成、查询结果数量) -->
<div aria-live="polite">查询到 12 条结果</div>
<!-- ↑ 内容变化时读屏自动播报(polite=等读完再播) -->
使用守则:①先原生后 ARIA;②ARIA 改变的是"读屏的理解",不改变任何行为(role="button" 的 div 还是不能按 Enter 触发,行为要自己写);③常见组件(下拉、标签页、弹窗)优先用成熟组件库(AntD,第 10 节装了)——它们的 ARIA 都调好了。
💡 地图场景:地图画布对读屏是"黑洞"。专业做法是提供数据表格替代视图("查看为表格"按钮)——W-2 数据平台会做这个功能。
六、SEO 关联
搜索引擎就是"最大的读屏用户":
- 一个
<h1>、标题层级不跳级(h1→h2→h3)——大纲即结构 <title>与<meta name="description">认真写(搜索结果的门面)- 关键内容不要只用图片;链接用描述性文字("OpenLayers 官网" ≠ "点这里")
- 语义化标签本身是排名信号;无障碍评分(Lighthouse Accessibility)是 Chrome 体检项(第 03 模块 Next.js 的 SEO 站会全面实践)
七、自测题
- 语义化的三层受益者分别获得什么?
<main>使用上有什么唯一性要求?- 装饰性图片的 alt 应该怎么写?省略 alt 属性行不行?
- ARIA 第一法则是什么?
aria-live="polite"的作用?
参考答案
- 辅助技术(可导航可朗读)、搜索引擎(结构与权重)、开发者(可读可维护)。
- 全页唯一。
- 写
alt="";不能省略属性(省略会被读屏当作"重要图片"去念文件名)。 - 能用原生 HTML 元素表达语义时,绝不用 ARIA。
- 标记一个"动态区域",内容变化时读屏自动播报新增内容,无需用户聚焦。
八、下一步
结构语义封顶 → 第 29 节:层叠/继承/优先级全解,把"谁说了算"的完整算法讲透。