跳到主要内容
全部文章

2026年9月18日·阅读约 2 分钟

地标结构:屏幕阅读器如何浏览页面

屏幕阅读器用户在页面地标之间跳转,而不是从上到下阅读。这是破坏这张“地图”的原因,以及修复方法。

landmarksaccessibilitywcaghtml5wcag-1-3-1axe-core

屏幕阅读器用户不会像滚动文档那样从上到下阅读页面,他们在有名称的区域之间跳转:页眉、导航、主要内容、页脚,就像视力正常的用户目光直接跳到菜单栏,而不去阅读上面的所有内容。 这些区域称为地标(landmark),没有它们,屏幕阅读器用户只能按顺序读完所有内容,无法直接跳到自己真正要找的地方。

将网页的各个区域列成简单的跳转列表,与屏幕阅读器呈现地标的方式相同。

要点

  • 地标是语义化的 HTML 区域,<header>、<nav>、<main>、<footer>、<aside>,它们为页面提供一张看不见的地图。屏幕阅读器可以直接在它们之间跳转。
  • 没有地标,屏幕阅读器用户就必须按顺序听完所有内容:同一个导航菜单在每个页面、每一次都重复出现,无法跳过。
  • 一个页面应当恰好有一个 <main>。 多于一个会扰乱地标导航,并直接导致自动扫描失败。
  • 多个 <nav> 元素需要标签来区分。 两个导航区域都只被读作“导航”,用户无从得知哪个是哪个。
  • 把所有内容都包在通用 <div> 标签里而不用语义化元素,会彻底抹掉这张地图。 <div> 没有角色,所以屏幕阅读器无处可跳。

确切的错误信息及修复方法

如果扫描工具把您带到这里,以下是 axe-core(大多数自动无障碍检查工具背后的开源引擎)针对地标问题报告的信息。措辞与 axe-core 4.11 一致,并保留英文原样,与报告中显示的一致。

"Document does not have a main landmark"

这是规则 landmark-one-main(“文档应有一个 main 地标”)。页面没有 <main> 元素,也没有 role="main"。请把页面的主要内容包在唯一的 <main> 中,网站的页眉和页脚放在它之外。

"All page content should be contained by landmarks"

这是规则 region;在失败的元素上显示为 "Some page content is not contained by landmarks"。文字、图片或控件位于所有 <header>、<nav>、<main> 和 <footer> 之外。把每一项移到它所属的地标中,最常见的是 <main>。

"Document should not have more than one main landmark"

这是规则 landmark-no-duplicate-main。页面上有两个元素在充当 <main>,无论是通过标签还是 role="main"。保留承载页面真实内容的那个,把另一个改为 <div> 或带标签的 <section>。

"Landmarks should have a unique role or role/label/title (i.e. accessible name) combination"

这是规则 landmark-unique。两个同类型的地标,通常是两个 <nav> 元素,没有名称或名称相同。给每个地标各自的 aria-label,例如 aria-label="Main" 和 aria-label="Footer"。

"Main landmark should not be contained in another landmark"

这是规则 landmark-main-is-top-level。<main> 被嵌套在 <header>、<nav>、<aside> 或 <footer> 内。把它移出来,使其处于页面的顶层。

其中哪些由 Axeazy 自动修复、哪些等待您批准,见下文“Axeazy 在这里能修复什么”。地标是屏幕阅读器用户在页面中移动的两种方式之一;另一种是标题,详见会破坏无障碍的标题结构错误。

地标究竟起什么作用

地标是标示页面主要区域的语义化 HTML 元素:<header> 用于顶部区域,<nav> 用于导航菜单,<main> 用于人们真正要阅读的内容,<footer> 用于底部内容,<aside> 用于侧边栏这类间接相关的内容。

每一个都带有屏幕阅读器自动识别的隐含角色。这正是它们成为地标而不仅是容器的原因:屏幕阅读器可以列出页面上的每个地标,让用户直接跳到其中任何一个,这与视力正常的用户只要扫一眼页面视觉布局就能免费获得的捷径是一样的。

屏幕阅读器的快捷键因软件而异,但思路处处相同:NVDA 用户用 D 键在地标间循环,JAWS 用户用 R 键,VoiceOver 用户通过转子。三者都能让人跳过重复的页眉和导航菜单,直达真正的内容,而那个菜单他们在网站其他每个页面上都已经听过了。

为什么这比看上去更重要

从头到尾阅读页面与使用地标直接跳到主要内容的对比。

想象一下,每个网站都被一口气不间断地读给您听:标志、完整的导航菜单、各种公告横幅,最后才是页面的真正内容,每个页面都如此,且无法跳过。这就是没有地标时的体验。在网店里浏览十个商品页面的人,要把完整的页眉和导航听上十遍,才能到达自己真正想比较的内容。

地标把这条直线变成了一张真正的地图。这就是 A 级的 WCAG 1.3.1“信息和关系”:页面结构和关系必须能被程序确定,而不仅仅是视觉上显而易见。它还与 2.4.1“绕过块”相关,即用户必须有办法跳过重复内容;地标是满足这一要求的标准方法之一。

破坏这张地图的常见错误

把所有内容都包在 <div> 里,而不用语义化元素。 <div> 完全没有角色。视觉上它可能与规范的 <header> 或 <nav> 一模一样,但屏幕阅读器无处可跳,这个地标根本不存在。

<!-- 失败:视觉上是页眉,对地标导航不可见 -->
<div class="header">
  <div class="logo">Site Name</div>
</div>

<!-- 通过:屏幕阅读器可以跳转的真正地标 -->
<header>
  <a href="/zh-hans" class="logo">Site Name</a>
</header>

一个页面上有多个 <main>。 HTML 规范只允许一个。第二个不仅是违反规则,还会主动扰乱地标导航,并导致自动扫描失败。

多个没有标签的 <nav> 元素。 如果页面有主导航菜单和单独的页脚导航,屏幕阅读器会把两者都读成“导航”,无法区分,除非每个都带有区别性的标签。

<!-- 失败:两者都被读成相同的、无标签的 "navigation" -->
<nav>...</nav>
<nav>...</nav>

<!-- 通过:每个都被区别地读出 -->
<nav aria-label="Main">...</nav>
<nav aria-label="Footer">...</nav>

把 <header> 或 <footer> 嵌套在 <article> 或 <section> 内。 这样嵌套后,它们会完全失去地标角色;只有在文档顶层时才会被识别为页面级地标,而不是在另一个内容区域内。

使用没有标签的 <section>。 <section> 只有通过 aria-label 或 aria-labelledby 获得可访问名称时,才成为真正的地标。没有标签的 <section> 根本不会被登记为地标。

如何检查您自己的网站

您不需要安装屏幕阅读器就能发现其中大部分问题。

两个外观相同的页眉,一个用 div 构建,一个用真正的 header 元素构建,只有一个是真正的地标。

  1. 查看页面源代码或打开 DevTools 的 Elements 面板。 搜索 <div class="header"> 或类似内容,用通用容器顶替真正地标元素是最常见的失败。
  2. 数一数您的 <main> 元素。 每个页面应当恰好有一个。
  3. 检查每个 <nav> 是否有标签,如果页面上有多个的话。
  4. 或者运行扫描,而不是逐个元素检查。 Axeazy 的免费扫描大约 60 秒就能检查页面的完整地标结构,同时涵盖它支持的其他修复类别。

Axeazy 在这里能修复什么

流程图:缺失的地标标签会被自动修复,而地标的结构性更改则等待批准。

这一类别干净地分成两种更改,只有一种可以在不先询问的情况下进行。

添加缺失的标签是纯粹的添加:不移动任何东西,不重命名任何东西,所以 Axeazy 会自动修复:没有标签的孤立内容区域会得到一个根据其 id、class 或标签名生成的标签,缺少区别性标签的重复地标会被加上一个。两者都是真实可用的自动修复。

重构现有地标,例如把重复的 <header> 改为普通 <div>、把嵌套的 <main> 移到顶层、修复被埋在不该在的位置的 <nav>,是可见的结构性更改,而不是悄悄的添加。Axeazy 会为这些情况计算出正确的修复方案,但在您或您的开发人员在控制面板中明确批准之前,不会写入任何内容。这是一条刻意的界线:添加一个不可见的标签不需要批准,更改页面的实际结构则需要。

常见问题

一个页面应该有多少个 <main> 元素?

恰好一个。HTML 规范只允许一个,多于一个会破坏屏幕阅读器用户的地标导航,并导致自动无障碍扫描失败。

我需要给页面上的每个 <nav> 都加标签吗?

只有在有多个时才需要。单个导航区域不需要标签,屏幕阅读器把它读作“导航”,意思很明确。一旦有两个或更多,每个都需要区别性的标签,如 aria-label="Main" 或 aria-label="Footer",以便用户区分。

使用 <section> 会自动创建地标吗?

不会。<section> 只有在拥有可访问名称(通过 aria-label 或 aria-labelledby 提供)后才成为地标。没有的话,它只是一个通用容器,在地标方面与 <div> 没有区别。

我可以把 <header> 嵌套在 <article> 里吗?

可以,但这样嵌套后它会失去页面级地标角色。<header> 或 <footer> 只有直接位于页面层级时才会被识别为顶层地标,而不是位于另一个内容区域内。

只修复地标就能让我的网站易于浏览吗?

没有任何单一修复能涵盖一切。地标解决的是一个特定问题:让用户在主要区域之间跳转,而不是按顺序阅读全部内容。页面仍可能有其他导航问题,如标题结构错乱或令人困惑的 Tab 键顺序,需要各自单独检查。

参考来源

想在邮箱中收到这类内容吗?

The ADA Alert。每周资讯。

每周二:无障碍新闻、常见 WCAG 问题以及代码层面的修复。免费。一键退订。 本简报以英文撰写。

我们交付的每份报告的范围: 范围限制:本报告记录的是使用 axe-core v4.11.0 进行 WCAG 2.2 AA 自动扫描所发现的违规问题。自动化工具无法测试所有 WCAG 准则;许多准则需要人工审查。本报告不构成法律建议,不保证符合 ADA,也不能防止法律诉讼。是否符合 ADA 是由法院作出的法律认定。如需完整的 WCAG 符合性评估,请聘请获得 IAAP 认证的无障碍专业人士。