资讯文章 资讯 · NEWS
语义标签之外还要补的那层:目录站的 landmark、跳转链接和 aria-current 该怎么加
2026-10-24 约 1,909 字 预计阅读 5 分钟 yiyunkj
语
语义标签解决的是「这块区域是什么」,ARIA 解决的是「这几块同名区域哪个是哪个」「现在在哪」。两者是接力关系,不是替代关系。
WAI-ARIA 里定义了八个 landmark 角色:banner、navigation、search、main、region、complementary、form、contentinfo。目录站真正用得上的一般是五个,而且大部分已经有对应的 HTML 元素了。

图片来源:网络,版权归原作者所有,侵权请联系删除
用得上的五个,和它们对应的标签
| landmark 角色 | 对应 HTML 元素 | 目录站用在哪 |
|---|---|---|
| banner | header(不在分节元素内时) | 顶部站头,含 logo 和主搜索 |
| navigation | nav | 主导航、分类导航、分页 |
| search | form role="search" | 搜索框容器 |
| main | main | 每页唯一的主体内容 |
| contentinfo | footer(不在分节元素内时) | 页脚,含备案号和声明链接 |
规范里的建议是:能用原生元素就用原生元素,不要往 div 上堆 role。在老浏览器兼容上,「语义元素 + 冗余 role」这种写法是可接受的,比把 role 加在 div 上好;但两者至少要有一样,否则屏幕阅读器用户就得在页面里线性摸索。
多个 nav 一定要有名字
目录站的页面常常有四五个 nav:顶部主导航、分类列表、面包屑、分页、页脚导航。它们对屏幕阅读器来说长得一模一样,用户听到的会是「导航、导航、导航、导航」。
解决办法是给每个 nav 一个可访问名称,优先用可见标题通过 aria-labelledby 引用,没有可见标题时用 aria-label:
<nav aria-label="分类导航"> ... </nav>
<nav aria-label="分页"> ... </nav>
名称要写用途,不要写位置。「分类导航」比「左侧导航」好——屏幕阅读器用户不关心它在左边还是右边,而且窄屏下它也不一定在左边。
aria-current:把「你现在在这儿」说出来
视觉上,当前分类是高亮的、当前页码是加粗的。这个信息对屏幕阅读器来说是缺失的,要靠 aria-current 补上。
<a href="/cate/design" aria-current="page">设计素材</a>
<a href="?page=3" aria-current="page">3</a>
常用值是 page(当前页面,用于分页和导航)、true(通用,比如步骤条里当前这一步)、date(日历里的今天)。同一组里应当只有一个元素带这个值——如果分类导航和面包屑都标了当前分类,用 page 的只留面包屑那一个,其余用 true 或者直接不标,避免读屏器反复播报。
跳转到主内容那条链接
目录站每个页面顶部都有几十个导航链接,键盘用户从地址栏按 Tab 进来,要按几十次才能摸到内容。标准做法是在 body 最前面放一条隐藏的跳转链接,聚焦时才显示:
.skip-link {
position: absolute; left: -9999px;
}
.skip-link:focus {
left: 8px; top: 8px;
background: #fff; padding: 8px 12px;
}
两个注意点:目标元素要能被聚焦(给 <main> 加 tabindex="-1"),以及别用 display: none 隐藏——那样键盘永远聚焦不到它,链接等于不存在。
顺带一提,加了正确的 landmark 之后,屏幕阅读器本身就有了区域跳转能力,但这不能替代这条可见的跳转链接,因为 landmark 对键盘和视力正常的其他用户是不可见的。
搜索结果的动态播报
站内搜索改成异步之后,结果变了但屏幕阅读器不知道。给结果容器加一个 role="status" 加 aria-live="polite",变化就会被播报:
<div role="status" aria-live="polite">找到 27 个站点</div>
用 polite 不要用 assertive——后者会打断用户当前正在听的内容。另外这个容器要在页面加载时就存在(哪怕是空的),动态插入的容器往往不会被正确监听。防抖之后的最终状态播报一次就够了,别每个字都播。
加了等于没加的三种写法
- div 上堆 role,语义元素一个不用。能用 header/nav/main 的地方就用,role 只是兜底。
- aria-label 写成图标名或英文类名。「nav-primary」「menu-1」这种名字对用户毫无意义,写用途。
- 给每个链接都加 aria-current。它的语义是「这组里当前这一个」,全标等于全没标。
这套东西和语义标签、和无障碍那几处改造是同一件事的三个层次:先有正确的元素,再有正确的区域名,最后补上动态状态。顺序反了会做很多无用功。