HTML landmark roles for improved accessibility, learn about landmark roles and how to use them, May 15, 2023

使用 HTML 地标角色提升可访问性

作者头像Schalk Neethling阅读时间:12 分钟

确保您的网站对所有用户(包括使用屏幕阅读器等辅助技术的用户)可访问非常重要。一种方法是使用ARIA 地标角色来帮助屏幕阅读器用户轻松浏览您的网站。使用地标角色还有其他好处,例如改进 HTML 的语义并使网站更容易进行样式化。在本博文中,我们将更仔细地了解这些地标以及如何在您的网站上使用它们,并提供一个简单的示例。

什么是 HTML 地标角色?

地标在可访问富互联网应用程序 (ARIA) 规范中定义为用户可能希望快速访问的页面区域。虽然没有明确说明这是专门为屏幕阅读器用户设计的,但它们是尤其对这一群体用户有帮助的一组角色。ARIA 规范中定义了八个地标角色

  • 横幅
  • 导航
  • 搜索
  • 主体
  • 区域
  • 补充
  • 表单
  • 内容信息

为元素分配特定角色的一种方法是在元素上使用role属性。例如

html
<div class="banner" role="banner"></div>

虽然在某些情况下您可能需要显式设置元素的角色,但某些 HTML 元素已经关联了角色。在本帖的其余部分,我们将遵循ARIA 的第一条规则,内容如下:

如果您能够使用具有您所需语义和行为的原生 HTML 元素或属性,而不是重新利用元素并添加 ARIA 角色、状态或属性以使其可访问,那么请这样做。

如何使用地标角色

为了说明 HTML 地标的工作原理,我们将构建一个基本的网页,以改善屏幕阅读器用户的用户体验和可访问性。我们不会编写任何 CSS,而是专注于编写简洁、语义化的 HTML。

将以下 HTML 保存到名为index.html的文件中,并在您喜欢的浏览器中打开它。

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Mr. Pineapple's Pizzeria</title>
  </head>
  <body></body>
</html>

您应该会看到一个空白页面,浏览器标签页中显示标题“Mr. Pineapple's Pizzeria”。对于每个地标,我们将添加相应的 HTML 并检查可访问性树以查看其如何变化。

横幅地标

横幅地标用于识别网页的页眉,其中通常包含网站的徽标、导航和搜索输入。当<header>元素用作<main>元素或其他分节元素的子元素时,会分配banner角色。

让我们看看通过向页面添加横幅地标后会是什么样子。

html
<body>
  <header>
    <a class="logo" href="/">
      <span class="visually-hidden">Mr. Pineapple's Pizzeria</span>
    </a>
  </header>
</body>

刷新页面并打开开发者工具。根据您使用的浏览器,访问可访问性树的方式会有所不同。您可以按照以下链接了解更多信息

  • Firefox
  • Chromium(Edge、Chrome、Arc)
  • 在 Safari 中,打开开发者工具(称为 Web 检查器)。在“元素”选项卡中选择一个元素。在最右侧,选择“节点”选项卡并展开“可访问性”部分。

Safari web inspector panel with the node tab selected. It shows the expanded accessibility tree inspector at the bottom of the panel.

从屏幕截图中可以看到,选择了<header>元素后,角色显示为banner。我们已经取得了良好的开端!

注意 Firefox 开发者工具的可访问性检查器不会显示元素的相应角色。相反,它会将所有这些元素的角色显示为“地标”。这个问题已得到解决,并将出现在 Firefox 114 中。如果您使用的是Firefox for developers,则问题已解决。

导航地标

navigation地标用于识别一组帮助用户浏览网页或相关网页的链接。这可能包括侧边栏导航、网站的主导航或页面页脚中的一组相关链接。

如前所述,页眉中常见元素之一是网站的主要导航。让我们在页面中添加一个。

html
<nav aria-label="Primary">
  <ul>
    <li><a aria-current="page" href="/">Home</a></li>
    <li><a href="/menu">Our pizzas</a></li>
    <li><a href="/contact">Get in touch</a></li>
  </ul>
</nav>

在这里,我们使用<nav>元素,因为它隐式地具有navigation角色。由于一个页面可能有多个导航元素,因此务必唯一地识别每个地标。为此,我们使用aria-label属性并将导航地标命名为“主要”。

注意 当屏幕阅读器描述上述导航地标时,会说“主要导航”。这就是为什么aria-label值中不包含“导航”一词。

如果您检查<nav>元素,您会注意到两件事:该元素被识别为导航地标,并公开了我们使用aria-label分配的值。

Shows the nav element highlighted in the elements inspector. It shows the accessibility inspector identifying the element as a navigation landmark with the name "Primary".

搜索地标

search角色用于对一组相关元素进行分组,这些元素共同提供了一种搜索网站的方法。使用此角色最常见的方法是通过表单。

html
<form name="site-search" action="/search" method="get" role="search">
  <label for="query">Find your perfect pizza</label>
  <input type="search" id="query" name="query" />
</form>

在这里,我们遇到了第一个需要显式分配角色的实例。由于没有具有搜索隐式角色的原生 HTML 元素,因此在本例中,我们将角色分配给<form>元素。这将随着我们将在本文后面讨论的新 HTML 元素的引入而发生变化。

如果您使用开发者工具检查表单元素,您将看到它正确地将地标识别为搜索地标

Shows the search form highlighted in the elements inspector. Below it shows the accessibility inspector identifying the element as a search navigation landmark.

主体地标

我们现在正从页眉移至页面的主要内容。这引入了下一个地标,恰如其分地命名为main。需要注意的是,一个页面只能有一个<main>元素

Shows the main element highlighted in the elements inspector. Below it shows the accessibility inspector identifying the element as the main navigational landmark.

在开发者工具中选择<main>元素,现在将正确识别我们的主要内容。

区域地标

我们的主要内容可以由不同类型的內容或区域组成,幸运的是,有一个角色可以对应这种情况。region角色很有趣;从技术上讲,确实有一个 HTML 元素具有region的隐式角色,但该元素有点争议。

我指的是<section>元素,或者有些人称之为“换个名字的<div>”。争议的原因是,当像下面示例中那样使用时,它没有任何语义含义

html
<section>
  <h2>Our pizzas</h2>
  <ul>
    <li>Margherita with pineapple</li>
    <li>Veggie with pineapple</li>
    <li>Meaty with pineapple</li>
  </ul>
</section>

使用开发者工具检查它也会显示它没有被识别为区域导航地标

Shows the section element highlighted in the elements inspector. In the accessibility inspector the section is not identified as a region navigation role.

那么如何将其转换为区域呢?我们可以使用aria-labelledby属性将标题元素与该部分关联来实现。这有两个目的:它将该部分转换为区域导航地标,而标题则为该区域提供唯一名称。

在极少数情况下,没有标题与<section>元素关联,您也可以使用aria-label属性来实现相同的结果。让我们更新之前的代码来实现这一点

html
<section aria-labelledby="our-pizzas-heading">
  <h2 id="our-pizzas-heading">Our pizzas</h2>
  <p>
    All our pizzas come with the best pizza topping in the world. Pineapple!
  </p>
  <ul>
    <li>Margherita with pineapple</li>
    <li>Veggie with pineapple</li>
    <li>Meaty with pineapple</li>
  </ul>
</section>

现在,当您检查<section>元素时,它将被正确识别为区域地标,并显示从标题元素继承的名称

Shows the section element highlighted in the elements inspector. In the accessibility inspector the section is correctly identified as a region navigation role.

在此阶段,必须重申使用地标的原因。地标旨在识别用户最可能感兴趣并希望导航到的页面的关键区域。因此,在决定页面中哪些区域应突出显示为地标时,请谨慎考虑。

补充地标

complementary地标旨在识别与主要内容互补的内容,但在与主要内容分离时仍具有意义。这可能包括相关文章、放映时间或天气信息。对于我们的页面,我们将链接到一些很棒的披萨食谱。

这一次,我们确实有一个可以用于补充地标的原生 HTML 元素

html
<aside aria-labelledby="pizza-recipe-heading">
  <h3 id="pizza-recipe-heading">Make your own pie!</h3>
  <p>Below is a list of our favorite pizza recipes.</p>
  <ul>
    <li><a href="/mushroom-pizza">The shroom</a></li>
    <li><a href="/smokey-joe">Smokey Joe</a></li>
    <li><a href="/fromage">Fromage</a></li>
  </ul>
</aside>

<aside>元素具有补充的隐式角色,因此非常适合我们的需求。因为在一个页面上可以有多个补充区域,所以务必唯一且描述性地命名每个区域。我们可以通过将标题元素与aria-labelledby属性关联或在<aside>元素上使用aria-label来实现。

在开发者工具中检查该元素将显示它被识别为补充导航地标角色,并从关联的标题元素继承其名称。

Shows the aside element highlighted in the elements inspector. In the accessibility inspector the section is correctly identified as a complementary navigation role.

表单地标

乍一看,这似乎很明显,如果不是因为与之前针对<section>元素讨论的类似重要细微差别的话。让我们在页面中添加一个时事通讯订阅表单。

html
<div class="newsletter">
  <h3>Subscribe to Mr. Pineapple's newsletter</h3>
  <p>
    In our newsletter, you can expect even more wonderful pizza recipes, all
    featuring the versatile pineapple.
  </p>
  <form name="newsletter" action="/subscribe" type="post">
    <label for="email">Please provide your email address</label>
    <input type="email" id="email" name="email" />

    <button type="submit">Pineapple Me 🍍</button>
  </form>
</div>

如果您检查<form>元素,您可能会失望地发现它没有被识别为表单地标,而是泛型部分

Shows the form element highlighted in the elements inspector. In the accessibility inspector the form is not identified as a form navigation role.

怎么回事?与之前的<section>元素一样,您需要将标题元素与表单关联或使用aria-label属性。我们已经有了一个描述性标题,因此我们只需将标题与表单关联即可。

html
<div class="newsletter">
  <h3 id="newsletter-subscribe-form-heading">
    Subscribe to Mr. Pineapple's newsletter
  </h3>
  <p>
    In our newsletter, you can expect even more wonderful pizza recipes, all
    featuring the versatile pineapple.
  </p>
  <form
    aria-labelledby="newsletter-subscribe-form-heading"
    name="newsletter"
    action="/subscribe"
    type="post">
    <label for="email">Please provide your email address</label>
    <input type="email" id="email" name="email" />

    <button type="submit">Pineapple Me 🍍</button>
  </form>
</div>

进行这些更改后,检查表单元素将得到预期的结果

Shows the form element highlighted in the elements inspector. In the accessibility inspector the form is correctly identified as a form navigation role.

内容信息地标

contentinfo 路标用于标识有关网页的信息,例如版权信息或指向隐私声明的链接。此路标最常见的用例是页面的页脚。在这里,我们再次拥有一个能够帮助我们的原生 HTML 元素。

html
<footer>
  <p>Copyright &copy; Mr. Pineapple's Pizzeria - 2023</p>
</footer>

<header> 元素一样,重要的是 <footer> 元素不能位于 <main> 元素或其他分节元素内。如果是这样,它将不会具有 contentinfo 的隐式角色。由于我们的 <footer> 元素是 <body> 元素的直接子元素,因此在开发者工具中检查它将得到预期的结果。

Shows the footer element highlighted in the elements inspector. In the accessibility inspector the footer is correctly identified as a contentinfo navigation role.

一个新的搜索 HTML 元素

我们现在已经涵盖了所有路标角色,并且对于每个路标,我们都有一个可以使用的原生 HTML 元素。当然,对于 regionform 路标,我们不得不做一些额外的工作,但我们从未需要显式地使用 role 属性。

但是等等,search 路标呢?我们确实必须在表单上使用 role 属性。糟糕,你抓到我了!但我确实说过,我稍后会在文章中给你一个惊喜。随着新 <search> 元素的引入,必须显式地为表单分配 search 角色的日子即将结束。那么,我们如何使用它呢?让我们更新我们之前搜索路标以使用新元素。

html
<search>
  <form name="site-search" action="/search" method="get" role="search">
    <label for="query">Find your perfect pizza</label>
    <input type="search" id="query" name="query" />
  </form>
</search>

不过,这是处于技术前沿的生活,因此,如果您今天(2023 年初)检查 <search> 元素,您会发现它在辅助功能树中显示为被忽略。

Shows the search element highlighted in the elements inspector. In the accessibility inspector the search element is shown as ignored.

这就是我在嵌套的 <form> 元素上保留 role 属性的原因。一旦浏览器和屏幕阅读器开始实现 <search> 元素,表单上的 role 属性将不再需要。曾经有一段时间,<main> 元素也存在同样的问题,主要是由于 Internet Explorer 的支持不足,因此需要显式地向元素添加 role="main"

我们现在可以退一步,看看我们一起构建的辉煌的辅助功能树。

Shows the full accessibility tree which includes all of the landmark navigational role we have created.

它很美,不是吗?

在 Chrome 中启用完整的辅助功能树

请注意,在 Chromium 浏览器中显示此树是一个实验性功能。在开发者工具中选择辅助功能选项卡后,您应该会看到一个条目,内容为“启用全页辅助功能树”,左侧有一个未选中的复选框。

Shows the accessibility tab in the developer tools with the fullpage accessibility tree option visible.

选中复选框后,将显示一条通知,要求您重新加载 DevTools。单击按钮并重新加载 DevTools 后,您将在“元素”面板的右上方看到一个新的图标。单击此图标将显示完整的辅助功能树。

Shows the elements tab in the developer tools with the the new accessibility tree icon at the top right.

使用屏幕阅读器演示路标

最后,让我们看看我们的路标如何与屏幕阅读器一起工作。

总结

HTML 路标是使网页更容易被屏幕阅读器用户访问的重要工具。通过在网页上定义路标,您可以帮助用户更轻松地导航并快速找到他们需要的信息。请记住,尽可能使用合适的 HTML 元素并清晰地标记路标,以便用户知道它们的作用。

有用资源

关注 MDN 的最新信息

订阅 MDN 电子邮件简报,不错过任何关于最新 Web 开发趋势、技巧和最佳实践的更新。