
使用 HTML 地标角色提升可访问性
确保您的网站对所有用户(包括使用屏幕阅读器等辅助技术的用户)可访问非常重要。一种方法是使用ARIA 地标角色来帮助屏幕阅读器用户轻松浏览您的网站。使用地标角色还有其他好处,例如改进 HTML 的语义并使网站更容易进行样式化。在本博文中,我们将更仔细地了解这些地标以及如何在您的网站上使用它们,并提供一个简单的示例。
什么是 HTML 地标角色?
地标在可访问富互联网应用程序 (ARIA) 规范中定义为用户可能希望快速访问的页面区域。虽然没有明确说明这是专门为屏幕阅读器用户设计的,但它们是尤其对这一群体用户有帮助的一组角色。ARIA 规范中定义了八个地标角色
横幅
导航
搜索
主体
区域
补充
表单
内容信息
为元素分配特定角色的一种方法是在元素上使用role
属性。例如
<div class="banner" role="banner"></div>
虽然在某些情况下您可能需要显式设置元素的角色,但某些 HTML 元素已经关联了角色。在本帖的其余部分,我们将遵循ARIA 的第一条规则,内容如下:
如果您能够使用具有您所需语义和行为的原生 HTML 元素或属性,而不是重新利用元素并添加 ARIA 角色、状态或属性以使其可访问,那么请这样做。
如何使用地标角色
为了说明 HTML 地标的工作原理,我们将构建一个基本的网页,以改善屏幕阅读器用户的用户体验和可访问性。我们不会编写任何 CSS,而是专注于编写简洁、语义化的 HTML。
将以下 HTML 保存到名为index.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
角色。
让我们看看通过向页面添加横幅地标后会是什么样子。
<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 检查器)。在“元素”选项卡中选择一个元素。在最右侧,选择“节点”选项卡并展开“可访问性”部分。
从屏幕截图中可以看到,选择了<header>
元素后,角色显示为banner
。我们已经取得了良好的开端!
注意 Firefox 开发者工具的可访问性检查器不会显示元素的相应角色。相反,它会将所有这些元素的角色显示为“地标”。这个问题已得到解决,并将出现在 Firefox 114 中。如果您使用的是Firefox for developers,则问题已解决。
导航地标
navigation
地标用于识别一组帮助用户浏览网页或相关网页的链接。这可能包括侧边栏导航、网站的主导航或页面页脚中的一组相关链接。
如前所述,页眉中常见元素之一是网站的主要导航。让我们在页面中添加一个。
<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
分配的值。
搜索地标
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>
在这里,我们遇到了第一个需要显式分配角色的实例。由于没有具有搜索隐式角色的原生 HTML 元素,因此在本例中,我们将角色分配给<form>
元素。这将随着我们将在本文后面讨论的新 HTML 元素的引入而发生变化。
如果您使用开发者工具检查表单元素,您将看到它正确地将地标识别为搜索地标
主体地标
我们现在正从页眉移至页面的主要内容。这引入了下一个地标,恰如其分地命名为main
。需要注意的是,一个页面只能有一个<main>
元素。
在开发者工具中选择<main>
元素,现在将正确识别我们的主要内容。
区域地标
我们的主要内容可以由不同类型的內容或区域组成,幸运的是,有一个角色可以对应这种情况。region
角色很有趣;从技术上讲,确实有一个 HTML 元素具有region
的隐式角色,但该元素有点争议。
我指的是<section>
元素,或者有些人称之为“换个名字的<div>
”。争议的原因是,当像下面示例中那样使用时,它没有任何语义含义
<section>
<h2>Our pizzas</h2>
<ul>
<li>Margherita with pineapple</li>
<li>Veggie with pineapple</li>
<li>Meaty with pineapple</li>
</ul>
</section>
使用开发者工具检查它也会显示它没有被识别为区域导航地标
那么如何将其转换为区域呢?我们可以使用aria-labelledby
属性将标题元素与该部分关联来实现。这有两个目的:它将该部分转换为区域导航地标,而标题则为该区域提供唯一名称。
在极少数情况下,没有标题与<section>
元素关联,您也可以使用aria-label
属性来实现相同的结果。让我们更新之前的代码来实现这一点
<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>
元素时,它将被正确识别为区域地标,并显示从标题元素继承的名称
在此阶段,必须重申使用地标的原因。地标旨在识别用户最可能感兴趣并希望导航到的页面的关键区域。因此,在决定页面中哪些区域应突出显示为地标时,请谨慎考虑。
补充地标
complementary
地标旨在识别与主要内容互补的内容,但在与主要内容分离时仍具有意义。这可能包括相关文章、放映时间或天气信息。对于我们的页面,我们将链接到一些很棒的披萨食谱。
这一次,我们确实有一个可以用于补充地标的原生 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
来实现。
在开发者工具中检查该元素将显示它被识别为补充导航地标角色,并从关联的标题元素继承其名称。
表单地标
乍一看,这似乎很明显,如果不是因为与之前针对<section>
元素讨论的类似重要细微差别的话。让我们在页面中添加一个时事通讯订阅表单。
<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>
元素,您可能会失望地发现它没有被识别为表单地标,而是泛型部分
怎么回事?与之前的<section>
元素一样,您需要将标题元素与表单关联或使用aria-label
属性。我们已经有了一个描述性标题,因此我们只需将标题与表单关联即可。
<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>
进行这些更改后,检查表单元素将得到预期的结果
内容信息地标
contentinfo
路标用于标识有关网页的信息,例如版权信息或指向隐私声明的链接。此路标最常见的用例是页面的页脚。在这里,我们再次拥有一个能够帮助我们的原生 HTML 元素。
<footer>
<p>Copyright © Mr. Pineapple's Pizzeria - 2023</p>
</footer>
与 <header>
元素一样,重要的是 <footer>
元素不能位于 <main>
元素或其他分节元素内。如果是这样,它将不会具有 contentinfo
的隐式角色。由于我们的 <footer>
元素是 <body>
元素的直接子元素,因此在开发者工具中检查它将得到预期的结果。
一个新的搜索 HTML 元素
我们现在已经涵盖了所有路标角色,并且对于每个路标,我们都有一个可以使用的原生 HTML 元素。当然,对于 region
和 form
路标,我们不得不做一些额外的工作,但我们从未需要显式地使用 role
属性。
但是等等,search
路标呢?我们确实必须在表单上使用 role
属性。糟糕,你抓到我了!但我确实说过,我稍后会在文章中给你一个惊喜。随着新 <search>
元素的引入,必须显式地为表单分配 search
角色的日子即将结束。那么,我们如何使用它呢?让我们更新我们之前搜索路标以使用新元素。
<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>
元素,您会发现它在辅助功能树中显示为被忽略。
这就是我在嵌套的 <form>
元素上保留 role
属性的原因。一旦浏览器和屏幕阅读器开始实现 <search>
元素,表单上的 role
属性将不再需要。曾经有一段时间,<main>
元素也存在同样的问题,主要是由于 Internet Explorer 的支持不足,因此需要显式地向元素添加 role="main"
。
我们现在可以退一步,看看我们一起构建的辉煌的辅助功能树。
它很美,不是吗?
在 Chrome 中启用完整的辅助功能树
请注意,在 Chromium 浏览器中显示此树是一个实验性功能。在开发者工具中选择辅助功能选项卡后,您应该会看到一个条目,内容为“启用全页辅助功能树”,左侧有一个未选中的复选框。
选中复选框后,将显示一条通知,要求您重新加载 DevTools。单击按钮并重新加载 DevTools 后,您将在“元素”面板的右上方看到一个新的图标。单击此图标将显示完整的辅助功能树。
使用屏幕阅读器演示路标
最后,让我们看看我们的路标如何与屏幕阅读器一起工作。
- 观看 Mozilla 开发者网站上的视频,该视频展示了屏幕阅读器用户如何使用我们的路标进行导航。
- 查看此文章的 CodeSandbox,以尝试我们上面创建的页面在其完成形式。
总结
HTML 路标是使网页更容易被屏幕阅读器用户访问的重要工具。通过在网页上定义路标,您可以帮助用户更轻松地导航并快速找到他们需要的信息。请记住,尽可能使用合适的 HTML 元素并清晰地标记路标,以便用户知道它们的作用。