通过HTML属性来增强网站和应用程序的可访问性

译文 精选
开发 前端
你曾经在 HTML 语言中使用过某个属性,却并未完全明白它的用途吗?你并非个例!随着时间的推移,我深入探究了众多HTML属性背后的含义,特别是那些对于可访问性极为关键的属性。

译者 | 刘涛

审校 | 重楼

你曾经在 HTML 语言中使用过某个属性,却并未完全明白它的用途吗?你并非个例!随着时间的推移,我深入探究了众多HTML属性背后的含义,特别是那些对于可访问性极为关键的属性。

在这个深入的教程里,我将剖析一些增强可访问性的关键HTML属性,阐释它们的作用以及何时有效地运用它们。

先决条件

要学习本教程,你应该对HTML具备基本的认识,并且对Javascript知识稍有了解。

目录

  1. 什么是ARIA属性?
  2. alt属性
  3. aria-label属性
  • 使用 aria-label的最佳实践
  1. aria-labelledby属性
  • aria-label和aria-labelledby有什么不同
  • 使用 aria-labelledby的最佳实践
  1. aria-describedby属性
  • 使用 aria-describedby 的最佳实践
  1. role属性
  • 常见的 role 值
  • 使用 role 属性的最佳实践
  1. aria-controls属性
  • 使用 aria-controls 的最佳实践
  1. aria-selected属性
  • 使用 aria-selected 的最佳实践
  1. tabindex属性
  • tabindex可能的值
  • 使tabindex的最佳实践
  1. title属性
  • title 的可访问性问题
  • 使用 title 属性的最佳实践
  1. 在 label 中使用 for 属性
  • 使用 for 属性的最佳实践
  1. scope 属性
  • 可能的 scope 值
  • 使用 scope 的最佳实践
  1. aria-hidden 属性
  • 使用 aria-hidden 的最佳实践
  1. inert属性
  • 使用 inert 的最佳实践
  1. aria-live 属性
  • aria-live 可能的值
  • 使用 aria-live 的最佳实践
  1. aria-roledescription属性
  • 使用aria-roledescription的最佳实践
  1. aria-atomic 属性
  • 使用 aria-atomic 的最佳实践
  1. 结论

1.什么是ARIA属性?

本文中列出的大多数属性都是ARIA属性。ARIA,全称为Accessible Rich Internet Applications(可访问富互联网应用),是由W3C(万维网联盟)定义的一组属性,旨在提升网络应用的可访问性。

ARIA属性为辅助技术(如屏幕阅读器)提供额外信息。正确运营这些属性可以使复杂的网络应用对视觉、听觉或运动障碍人士更加友好。

使用ARIA的一个关键原则是:有时最好不要使用它。尽管这听起来可能有些矛盾,但你应该仅在必要时才使用ARIA属性。过度使用ARIA可能会干扰依赖辅助技术的用户体验。虽然视力正常的用户可能察觉不到任何问题,但ARIA的过度或不当使用可能会对可访问性产生负面影响。

2.alt属性

如果已经HTML中使用过图片,那么alt属性对来说或许并不陌生。使用它来提供替代文本,这些文本会在图片无法在屏幕上正确显示时予以呈现

然而,alt属性最重要的用途在于可访问性。如果图片元素中缺失alt属性,那么屏幕阅读器可能会仅显示图片文件的名称或图片的URL,而不是解释它所展示的内容。这可能会对用户造成困扰,而我们不希望发生这种情况。

alt属性中的内容应该简洁明了,因为主要目的是为那些无法看到图片的人简要描述图片。这涵盖了依赖屏幕阅读器的用户、搜索引擎以及网络连接缓慢致使图片可能无法加载的用户。如果alt文本过长,可能会包含不必要的细节,这些细节不会增加用户对图片内容的理解。

alt属性与图片说明有所不同。图片说明是可见的,可以提供更多关于图片的上下文或额外信息。将图片说明用作alt文本可能会使其过长且冗余。

如果图片纯粹是装饰性的,那么alt属性应当为空图片有一个空的alt属性,辅助工具将会跳过它。这对于帮助用户专注于内容而不被不必要的信息分散注意力非常重要。

下面是一个如何使用alt属性的例子:

<p>Lions are remarkable for their powerful roars, 
which can be heard up to five miles away. 
These roars are used to communicate with other 
members of the pride, as well as to ward off rival lions and intruders. 
Although lions are often associated with the African savannah, 
a small population of Asiatic lions still exists in India's Gir Forest, 
making them one of the world's most endangered big cats.</p>

<img src="lion.jpg" alt="a lion" /> <!-- brief and gives context to the paragraph -->

<img src="background-stars.png" alt="" /> <!-- This image is purely for 
decoration so it's left empty -->

3.aria-label属性

aria-label属性用于为可能没有可见文本的元素提供一个可访问的名称。一个常见的例子是包含图像或 SVG 的按钮。

很多元素都有一个可访问的名称——可访问的名称是元素内部的内容。在这个例子中,标题的可访问名称是“Frequently Asked Questions”

<h1>Frequently Asked Questions</h1>

包括使用辅助技术的人员在内的每个人,都能清楚地理解上面这个例子的意思,因为它包含了可见的内容。

但在下面的例子中,倘若按钮没有aria-label,依赖屏幕阅读器的用户或许会错过按钮中的内容。这是因为按钮中的内容是一个SVG格式(Scalable Vector Graphics:可缩放矢量图),而SVG不包含任何可见的内容:

<button aria-label="Search">
 <svg
 fill="#000000" 
 height="20px"
 width="20px"
 xmlns="http://www.w3.org/2000/svg" 
 viewBox="0 0 488.4 488.4">
 <g stroke-width="0"></g>
 <g stroke-linecap="round" stroke-linejoin="round"></g>
 <g><g>
 <g>
 <path d="M0,203.25c0,112.1,91.2,203.2,203.2,203.2c51.6,0,98.8-19.4,134.7-51.2l129.5,129.5c2.4,2.4,5.5,3.6,8.7,3.6 s6.3-1.2,8.7-3.6c4.8-4.8,4.8-12.5,0-17.3l-129.6-129.5c31.8-35.9,51.2-83,51.2-134.7c0-112.1-91.2-203.2-203.2-203.2 S0,91.15,0,203.25z M381.9,203.25c0,98.5-80.2,178.7-178.7,178.7s-178.7-80.2-178.7-178.7s80.2-178.7,178.7-178.7 S381.9,104.65,381.9,203.25z" />
 </g> 
 </g></g>
 </svg>
</button>

不要过度使用aria-label。并非所有内容都需要aria-label——例如,如果你有一个包含带有alt的图像的按钮,或者带有title的 SVG,那么这些属性就充当了该元素的可访问名称。

<button>
 <img src="search-icon.png" alt="Search" /> <!-- no need for aria-label -->
</button>
<!-- Another example -->
<button>
 <svg
 fill="#000000"
 height="20px"
 width="20px"
 role="image"
 xmlns="http://www.w3.org/2000/svg"
 viewBox="0 0 488.4 488.4">
 <title>Search Icon</title> <!-- Accessible name -->
 <g stroke-width="0"></g>
 <g stroke-linecap="round" stroke-linejoin="round"></g>
 <g><g>
 <g>
 <path d="M0,203.25c0,112.1,91.2,203.2,203.2,203.2c51.6,0,98.8-19.4,134.7-51.2l129.5,129.5c2.4,2.4,5.5,3.6,8.7,3.6 s6.3-1.2,8.7-3.6c4.8-4.8,4.8-12.5,0-17.3l-129.6-129.5c31.8-35.9,51.2-83,51.2-134.7c0-112.1-91.2-203.2-203.2-203.2 S0,91.15,0,203.25z M381.9,203.25c0,98.5-80.2,178.7-178.7,178.7s-178.7-80.2-178.7-178.7s80.2-178.7,178.7-178.7 S381.9,104.65,381.9,203.25z" />
 </g> 
 <g><g>
 </svg>
</button>

你应该谨慎且适当地使用aria-label。过度使用该属性可能会导致几个问题:

  • aria-label的内容对视力正常的用户不可见。如果有认知障碍的用户使用屏幕阅读器获取支持,他们可能不理解为什么听到的信息与在屏幕上看到的不同。
  • 在大型代码库中广泛使用aria-label会使 HTML 更难维护。你可能难以跟踪标签的来源,特别是如果它们是通过编程方式设置的或在多个地方设置的。

使用aria-label的最佳实践

  • 只要有可能,就用可见文本标签。它们更易于理解和维护,并且能够为所有用户提供一致的体验。
  • 倘若页面上已经存在一个可见的标签,请使用 aria-labelledby 将元素与现有文本关联起来,而非使用 aria-label 创建一个新标签(我们稍后会探讨这一点)。
  • 如果你使用 aria-label,请让文本保持简短且切中要害,并用最少的词汇来描述元素的目的。

4.aria-labelledby属性

aria-labelledby属性用于将一个元素和另一个元素相关联,后者充当前者的标签。它能够把目标元素与页面上的一个或多个其他元素相连接,这些元素中包含的文本将作为目标元素的标签来使用。

你能够在已经存在可见的文本标签,或者标签需要由多个文本元素构成时运用此属性。

例如,你能够在<section>元素中使用aria-labelledby 属性,从而将其与标题或者其他文本相关联,这些文本可作为整个部分的标签。

<h2 id="about-heading">About Us</h2> 
<section aria-labelledby="about-heading"> <!-- use the id of the h2 -->
 <p>We are a company dedicated to providing excellent service...</p>
</section>
<h2 id="services-heading">Our Services</h2>
<section aria-labelledby="services-heading">
 <p>We offer a wide range of services including...</p>
</section>

有时,你可能将多个文本片段组合成标签可以通过在aria-labelledby属性中列出多个ID来实现这一点:

<h1 id="dialog-title">Confirmation Required</h1>
<p id="dialog-description">Are you sure you want to delete this item?</p>
<button aria-labelledby="dialog-title dialog-description">Yes</button>

aria-labelledby与aria-label在目的上是相似的,都是为了提供一个可访问的元素。

aria-label和aria-labelledby有什么不同

aria-label属性直接为元素指定一串文本作为标签。这段文本在屏幕上不可见,但会被屏幕阅读器等辅助技术朗读出来。它通常用于那些没有可见文本标签的情况。

而aria-labelledby属性则通过引用页面上已存在的一个或多个元素(利用这些元素的ID属性)来作为目标元素的标签。标签文本对所有用户都是可见的,因为它们本身就是页面上其他元素内容的一部分。

使用aria-labelledby的最佳实践

  • 当页面上已经存在可以作为标签的文本时,应优先使用aria-labelledby而不是aria-label。这样做可以减少冗余,并确保视力正常的用户和屏幕阅读器用户都能看到相同的内容。
  • aria-labelledby引用的ID属性在页面上必须是唯一的,并且必须正确地指向现有的元素。如果ID缺失或错误,标签将不会起作用,从而导致可访问性问题。
  • 当组合多个标签时,请确保组合后的标签在一起阅读时是有意义的。aria-labelledby中ID的顺序很重要,因为屏幕阅读器会按照列出的顺序来朗读标签。
  • 与aria-label一样,应避免在可以使用更简单方法(如直接使用可见的label元素)的情况下过度使用aria-labelledby。这有助于保持代码的可维护性,并减少用户的认知负担。

5.aria-describedby属性

aria-describedby属性用于将一个元素与一个或多个能为其提供额外描述性信息的元素相关联。aria-describedby属性用于为元素提供额外的上下文或说明。

与旨在提供标签或名称的aria-labelledby不同,aria-describedby旨在为用户提供有关元素的更详细的信息或上下文,通常是对他们从标签中已经了解到的内容的补充。

<label id="full-name">Full name</label>
<input type="text" aria-labelledby="full-name" aria-describedby="info">
<span id="info">Enter your full name.</span>

当在同一个元素上同时运用了 aria-labelledby 和 aria-describedby 属性时,屏幕阅读器会首先声明由 aria-labelledby 指定的标签,接着声明元素的角色(例如,“按钮”),最后声明由 aria-describedby 所提供的描述。

使用aria-describedby的最佳实践

  • 当你需要为用户提供超出标签范畴的额外上下文或说明时,应当使用“aria-describedby”属性。这对于表单、复杂控件或者任何可能需要加以澄清的元素而言特别有用。
  • 尽管“aria-describedby”旨在提供更为详尽的描述,但是应当避免使用过长的文本。要保持描述的内容专注于用户与元素有效交互所需要了解的信息。
  • 和“aria-labelledby”相同,请确保“aria-describedby”所引用的元素具备唯一且相关的“id”属性。这些元素的内容应当直接与它们所描述的元素相关联。

6.role属性

role属性用于指定元素的角色。你可以使用它来覆盖语义元素的默认角色,从而帮助辅助技术理解元素应该如何被解释或与之交互。

当你使用非语义元素(如<div>或<span>)来创建交互式控件(如按钮、对话框、选项卡等)时,role属性会向辅助技术传递元素的预期行为。这样,即使元素本身没有明确的语义含义,辅助技术也能正确地识别和处理它。此外,你还可以使用role属性来定义地标角色,这些角色有助于导航,如banner或complementary。这些地标角色定义了页面的结构,为屏幕阅读器用户提供了更好的导航体验。

常见的role值

地标区域的角色:

  • banner:代表网站的头部。
  • navigation:定义页面的导航部分,通常用于网站或页面的导航链接。
  • main:标记文档的主要内容,区别于侧边栏、页脚等。
  • contentinfo:代表页脚信息。

下面的这个示例仅用于演示目的——在可能的情况下,你应该使用正确的语义元素:

<div role="banner">
 <h1>My Website</h1>
</div>
<div role="navigation">
 <ul>
 <li><a href="#home">Home</a></li>
 <li><a href="#about">About</a></li>
 </ul>
</div>
<div role="main">
 <h2>Welcome to My Website</h2>
 <p>Here is some main content...</p>
</div>
<div role="contentinfo">
 <p>© 2024 My Website</p>
</div>

小部件和交互式元素的角色:

  • button:代表一个按钮元素,用户可以点击它来触发某个动作。
  • dialog:标记一个对话框或模态窗口,它要求用户进行交互。
  • alert:将一个元素标识为重要的消息或警告,需要用户注意。
  • tablist、tab和tabpanel:用于选项卡界面,其中tablist包含选项卡,tab控制其对应tabpanel的可见性。
<div role="button" tabindex="0" onclick="submitForm()">Submit</div>
<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
 <h2 id="dialog-title">Confirmation</h2>
 <p>Are you sure you want to proceed?</p>
 <button onclick="closeDialog()">Close</button>
</div>

选项卡面板的示例:

<div role="tablist" aria-label="Sample Tabs">
 <button role="tab" id="tab-1" aria-controls="panel-1" aria-selected="true" tabindex="0">Tab 1</button>
 <button role="tab" id="tab-2" aria-controls="panel-2" aria-selected="false" tabindex="-1">Tab 2</button>
 <button role="tab" id="tab-3" aria-controls="panel-3" aria-selected="false" tabindex="-1">Tab 3</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
 <h2>Content for Tab 1</h2>
 <p>This is the content of the first tab.</p>
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
 <h2>Content for Tab 2</h2>
 <p>This is the content of the second tab.</p>
</div>
<div role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>
 <h2>Content for Tab 3</h2>
 <p>This is the content of the third tab.</p>
</div>

使用role属性的最佳实践

  • 始终优先使用已经具有适当角色的原生HTML元素(例如,<button>、<header>、 <nav>、<main>)。如此能够在更广泛的浏览器和设备上提供更优的可访问性支持。
  • 切勿过度使用或误用role属性,因为这可能会导致混淆并降低可访问性。在有需要的时候,使用role来增强或澄清,而不是替换语义HTML。
  • 了解隐式角色。许多HTML元素具有隐式角色。例如,带有href属性的<a>元素自动具有link角色。避免向这些元素添加冗余的role属性。

7.aria-controls属性

aria-controls 属性会通知屏幕阅读器该元素由另一个元素所控制或者受其影响。它通常被用于声明一个组件(按钮或者选项卡)控制或者与页面的另一部分(如面板或者菜单)进行交互。它也应用于交互式组件,例如选项卡、折叠面板(accordions)和滑块,以描述当用户与组件进行交互时页面的哪些部分会受到影响。

例如,你能够在选项卡按钮上使用aria-controls来声明每个按钮控制所对应的面板:

<!-- Tab Buttons -->
<button id="tab1" aria-controls="panel1">Tab 1</button>
<button id="tab2" aria-controls="panel2">Tab 2</button>
<!-- Content Panels -->
<div id="panel1" role="tabpanel">Content for Tab 1</div>
<div id="panel2" role="tabpanel">Content for Tab 2</div>

使用aria-controls的最佳实践

  • 确保aria-controls中使用的ID与被控制元素的id属性完全匹配。
  • 将aria-controls与role和诸如aria-selected之类的状态属性或role="tabpanel"结合使用,以提供有关被控制元素及其状态的更完整信息。
  • aria-controls应用于诸如按钮或链接等对其他元素具有直接影响的交互式元素。它通常不用于非交互式内容。

8.aria-selected属性

aria-selected 属性用于声明一组可选项目当中某个元素的当前选择状态。可选项目可以是菜单中的选项、选项卡面板中的选项,或列表框中的项目。

以下是一个在列表框中选择状态的一个示例,选项1中的 aria-selected ="true"表示选项1目前被选中

<!-- Listbox -->
<ul role="listbox">
 <li role="option" aria-selected="true">Option 1</li>
 <li role="option" aria-selected="false">Option 2</li>
 <li role="option" aria-selected="false">Option 3</li>
</ul>

使用aria-selected的最佳实践

  • 对于选中的项目使用aria-selected="true",对于未选中的项目使用aria-selected="false"。这个值应是一个字符串,而布尔值。
  • 确保元素的可见状态(例如,活动的选项卡或选中项)与aria-selected的值相匹配。不一致的状态可能会导致使用辅助技术用户感到困惑。
  • 将aria-selected与适当的role属性(例如,对于列表框项目使用role="option")结合使用,以提供完整的上下文。
  • 确保在用户与界面交互时动态更新aria-selected。例如,当用户选择新选项时,相应地更新aria-selected属性。

9.tabindex属性

tabindex 属性用于把控元素的键盘导航。你能够用它为非交互式元素(例如 div、p 或者 span)激活焦点,或者为交互式元素(例如 button、a、input)禁用焦点。此外,你还能够使用 tabindex 来控制页面上的焦点顺序。

tabindex可能的值

正值:具有正值的元素将变得可聚焦,并且会按照它们的tabindex值被纳入到tab键的导航顺序中。tabindex值较小的元素会先于tabindex值较大的元素获得焦点。

<button tabindex="2">Cancel</button> <!-- This will recieve focus last -->
<button tabindex="1">Submit</button> <!-- This will recieve focus first -->

具有相同tabindex值的元素将依照它们在文档中出现的顺序进行导航。

注意:使用正值的tabindex或许会致使tab键的导航顺序变得混乱且不符合直觉。通常,对于应当按照自然顺序接收焦点的元素,使用tabindex="0"是更优的选择。

零值:你可以使用此选项来让一个元素变得可聚焦,并将其按照在文档中的位置自然地纳入到tab键的导航顺序中。这对于让那些通常不可聚焦的元素(如<div>或<span>)变得可聚焦极为有用。

<div role="button" tabindex="0">Submit</div> 
 <!-- The element becomes focusable using the keyboard -->

负值:在 tabindex 属性中使用负值,目的是将元素从 Tab 键的导航顺序里移除,这表示用户无法通过 Tab 键直接聚焦到该元素上。然而,这并不代表该元素完全不可聚焦;它依旧能够通过编程的方式(例如,使用 JavaScript)来接收焦点。这种设置对于那些默认情况下不应被聚焦,但在某些特定条件下可能需要被聚焦的元素尤其有用。

<input type="text" name="name">
 <input type="text" name="other-names" tabindex="-1">
 <input type="text" placeholder="email">
<!-- other-names will be skipped when tabbing through the inputs; 
 only name and email will receive focus -->

使tabindex的最佳实践

  • 尽可能依赖自然的Tab键导航顺序。使用tabindex="0"来将元素纳入到Tab键的导航顺序中,并避免在绝对必要时使用正值。
  • 使用正值的tabindex可能会创建不可预测的Tab键导航顺序,并增加用户导航的难度。更好的做法是使用默认的导航流和tabindex="0"。
  • 对于不打算被聚焦的元素,使用tabindex="-1"。
  • 确保焦点顺序遵循逻辑且直观的顺序,这与页面的视觉布局和交互流程相匹配。
  • 使用键盘和辅助技术进行测试。
  • 当动态添加或删除可聚焦元素(例如,通过JavaScript)时,请确保正确处理焦点管理,以保持流畅的用户体验。

10.title属性

在HTML中,title属性用于提供关于元素的附加信息。当用户将鼠标悬停在包含标题的元素上时,属性中的内容会以工具提示的形式显示。它可以应用于大多数HTML元素,包括链接、图片和表单字段。

你可以使用title属性来提供元素内容的简要解释或描述。例如,你可以在使用<abbr>标签时,通过它来声明缩略语或首字母缩略词的含义。

<abbr title="World Wide Web">WWW</abbr>
<!-- Hovering over "WWW" displays the tooltip "World Wide Web," 
explaining the abbreviation. -->
<img src="logo.png" 
alt="Company Logo" 
title="This is the logo of our company">
<!-- Users will see "This is the logo of our company" 
when hovering over the image. -->

title的可访问性问题

标题属性虽然具有一定的实用价值,但也存在一些可访问性问题

  • 屏幕阅读器对 title 属性的支持并不一致,特别是在存在 alt 属性的情况下,屏幕阅读器可能会忽略 title 属性。这使得依赖屏幕阅读器的辅助技术用户难以获取 title 属性所提供的信息。
  • 基于 title 属性生成的工具提示通常只在使用鼠标或触控板悬停时出现。因此,对于使用键盘或触摸屏进行导航的用户来说,他们可能无法获取该信息。
  • title 属性的内容在默认情况下是隐藏的,仅在悬停时才会显示。这导致那些不熟悉需要悬停以获取额外信息的用户无法充分利用这一属性,从而降低了其可访问性。
  • 工具提示的可读性较差,通常由于其迅速消失的特性,内容可能被截断,或者超出可容纳的长度,从而影响信息的呈现效果。

使用title属性的最佳实践

  • 避免仅依赖 title 属性。确保关键信息以更具可访问性的形式提供,例如可见文本或 ARIA 属性。
  • 将 title 属性用作补充性、非关键性的信息,以增强用户体验,但并不是内容理解的必要条件。
  • 对于表单输入,使用 aria-describedby 属性将附加说明与表单元素关联。应优先使用可见标签或描述,替代或补充 title 属性,以确保所有用户均能获取所需信息。
  • 如果使用 title 属性,请保持文本简短且切中要点。过长的工具提示可能难以阅读,并可能被截断。

11.在label标签中使用for属性

当在<label>中使用for属性时,它用于将标签与其对应的表单控件元素(即<input>、<select>或<textarea>)连接起来。当指定的输入获得焦点时,屏幕阅读器会声明该标签。当正确使用for属性时,点击标签会使对应的输入获得焦点。

for属性的值应该与它所关联的输入的id相匹配:

<label for="fullname">Full Name</label>
<input type="text" id="fullname">
<!-- When the user clicks on the "Full Name" label, 
the cursor will focus on the corresponding input field. -->

使用for属性的最佳实践

  • 务必确保每个表单控件都具备唯一的id属性,以便for属性能够准确无误地引用它。避免在同一页面上使用重复的 id值。
  • 杜绝使用空的for属性。倘若没有关联的表单控件,这可能会令辅助技术的用户产生困惑。
  • 将标签放置于与其关联的表单控件的附近。通常而言,为了实现最佳的可读性和可用性,标签应当放置在表单控件的上方或者左侧。

12.scope属性

在HTML表格中,scope属性用于定义<th>(表格头部)与其所描述的单元格之间的关系。这个属性对于可访问性尤为重要,因为它帮助屏幕阅读器和其他辅助技术理解表格的结构,并向用户传达正确的信息。

scope属性可以应用于<th>(表格头部)元素,以指定该头部是应用于一行、一列,还是一组行或列。

可能的scope值

  • row:声明<th>元素是行的标题。在下面的例子中,scope="row"用于每行的第一个<th>元素,表明该标题适用于整行。
<table>
 <tbody>
 <tr>
 <th scope="row">Product A</th>
 <td>$1000</td>
 <td>$1200</td>
 <td>$1100</td>
 </tr>
 <tr>
 <th scope="row">Product B</th>
 <td>$900</td>
 <td>$950</td>
 <td>$1000</td>
 </tr>
 </tbody>
</table>
  • col:声明<th>元素是列的标题。
<table>
 <thead>
 <tr>
 <th scope="col">Name</th>
 <th scope="col">Age</th>
 <th scope="col">Occupation</th>
 </tr>
<!-- The scope="col" attribute indicates that each <th> element 
serves as a header for the corresponding column beneath it. -->
 </thead>
 <tbody>
 <tr>
 <td>Jane</td>
 <td>30</td>
 <td>Engineer</td>
 </tr>
 <tr>
 <td>Tobe</td>
 <td>25</td>
 <td>Designer</td>
 </tr>
 </tbody>
</table>
  • rowgroup:声明<th>元素是一组行的标题。在下面的例子中,“Marketing Department”和“Sales Department”这两行具有scope="rowgroup"属性,以声明它们作为后续行组的标题。
<table>
 <thead>
 <tr>
 <th scope="col">Department</th>
 <th scope="col">Employee Name</th>
 <th scope="col">Position</th>
 <th scope="col">Salary</th>
 </tr>
 </thead>
 <tbody>
 <!-- Row Group for the Marketing Department -->
 <tr>
 <th scope="rowgroup" colspan="4">Marketing Department</th>
 </tr>
 <tr>
 <th scope="row">Amari Pere</th>
 <td>Marketing Manager</td>
 <td>$75,000</td>
 </tr>
 <tr>
 <th scope="row">Uyati Hope</th>
 <td>SEO Specialist</td>
 <td>$65,000</td>
 </tr>
<!-- Row Group for the Sales Department -->
 <tr>
 <th scope="rowgroup" colspan="4">Sales Department</th>
 </tr>
 <tr>
 <th scope="row">Timini Prosper</th>
 <td>Sales Manager</td>
 <td>$80,000</td>
 </tr>
 <tr>
 <th scope="row">Delilu Pink</th>
 <td>Account Executive</td>
 <td>$70,000</td>
 </tr>
 </tbody>
</table>
  • colgroup:表示 <th> 元素是一组列的标题。在下面的例子中,scope="colgroup" 用于声明第一行标题适用于多组列(Q1 和 Q2),而scope="col"和scope="row"分别用于单个列和行。
<table>
 <thead>
 <tr>
 <th scope="colgroup">Region</th>
 <th scope="colgroup">Q1</th>
 <th scope="colgroup">Q2</th>
 </tr>
 <tr>
 <th scope="col">Sales</th>
 <th scope="col">Profit</th>
 <th scope="col">Sales</th>
 <th scope="col">Profit</th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <th scope="row">North</th>
 <td>$2000</td>
 <td>$400</td>
 <td>$2500</td>
 <td>$500</td>
 </tr>
 <tr>
 <th scope="row">South</th>
 <td>$1500</td>
 <td>$300</td>
 <td>$1800</td>
 <td>$350</td>
 </tr>
 </tbody>
</table>

使用scope的最佳实践

  • 习惯为复杂表格定义scope属性,以明确表头和数据单元格之间的关系。
  • 尽可能简化表格结构。虽然scope属性有助于提高可访问性,但也要考虑在可能的情况下简化表格结构。如果表格过于复杂,即使使用了正确的标记,也可能让所有用户都难以理解。
  • 对于特别复杂的表格,请考虑使用ARIA属性(如aria-labelledby或aria-describedby)来提供额外的上下文信息,并确保所有用户都能有效地浏览表格。
  • 在应用scope属性后,请使用屏幕阅读器测试表格,以确保表头和数据单元格之间的关系被正确宣布。
  • 在不需要的情况下不要使用scope。对于简单的表格,如果每个表头都清楚地与单行或单列相关联,那么HTML的默认行为通常就足够了。

13.aria-hidden属性

“aria-hidden” 属性被设计用来在辅助技术(如屏幕阅读器)中控制元素的“可访问性”状态,即便这些元素在视觉呈现上依然对用户可见。通过应用此属性,开发者可以使用它来隐藏纯粹的装饰性元素,如图标或图像,这些元素不会为内容添加有意义的信息。这有助于防止屏幕阅读器读取不必要的信息。

<button>
 <span aria-hidden="true"></span>
 Search
</button>

你还可以使用aria-hidden来隐藏已经声明过的内容,以防止屏幕阅读器重复声明相同的信息。对于可以打开关闭的内容(如模态窗口或可扩展部分),可以使用aria-hidden来隐藏非活动状态的内容,确保屏幕阅读器仅与可见的活动内容交互。

<button>
 <span aria-hidden="true">✉</span> <!-- hide decorative icon -->
 <span>Messages</span>
</button>

也可以在创建复杂的控件(如轮播图或选项卡式界面)时使用 “aria-hidden”,以对辅助技术隐藏当前未激活的面板或幻灯片,从而引导辅助技术(如屏幕阅读器)将注意力集中在控件的激活部分上。

<div id="menu" aria-hidden="true">
 <!-- Menu content here -->
</div>
<button onclick="toggleMenu()">Toggle Menu</button>
<script>
 const toggleMenu = () => {
 const menu = document.getElementById('menu');
 const isHidden = menu.getAttribute('aria-hidden') === 'true';
menu.setAttribute('aria-hidden', !isHidden);
 }
</script>

使用aria-hidden的最佳实践

  • 仅在需要针对屏幕阅读器隐藏内容,以防止用户被冗余或无关的信息所淹没时,才使用“aria-hidden”。
  • 切勿在用户需要与之进行交互的元素(例如按钮或链接)上使用
  • 确保“aria-hidden”能够精准反映元素在屏幕上的可见性。倘若一个元素通过JavaScript或CSS变为可见或隐藏,要相应地更新“aria-hidden”,以维持可访问性。
  • 在团队环境当中,在代码库中记录为何以及在何处使用“aria-hidden”,以便其他团队成员理解其用途,并能够正确地对其进行维护。

14.inert属性

inert属性阻止元素及其所有后代元素成为可聚焦、可交互的,或者被辅助技术(如屏幕阅读器)感知。当一个元素具有 inert属性时,它无法接受焦点、被点击或以任何方式与之交互。同时,它也会被辅助技术隐藏。

与仅影响可访问性的aria-hidden不同,inert适用于所有用户交互。inert属性可用于禁用页面上暂时不相关的部分,例如在表单验证错误期间、加载数据时,或者当某个部分被隐藏但仍保留在DOM中时。它还可用于复杂的用户界面,如多步骤表单或向导,以确保用户仅与当前步骤或部分进行交互。

然而inert最常见的用途是在模态窗口中,此时你希望防止用户在模态窗口打开时与背景内容交互。

以下是一个示例,当模态窗口打开时,inert属性被添加到主要内容上,使其变为非交互式的,并从屏幕阅读器中隐藏。当模态窗口关闭时,inert属性被移除,主要内容再次变为可交互的。

<div id="main-content" inert>
 <p>This is the main content of the page. It will be inactive when the modal is open.</p>
</div>
<div id="modal" role="dialog" aria-modal="true">
 <h2>Modal Title</h2>
 <p>This is the content inside the modal.</p>
 <button onclick="closeModal()">Close Modal</button>
</div>
<script>
function openModal() {
 document.getElementById('main-content').setAttribute('inert', '');
 document.getElementById('modal').style.display = 'block';
}
function closeModal() {
 document.getElementById('main-content').removeAttribute('inert');
 document.getElementById('modal').style.display = 'none';
}
</script>

使用inert的最佳实践

  • 确保在使用inert属性时,元素的视觉非活动或禁用状态对视力正常的用户来说是清晰的。例如,在模态窗口打开时,可以通过调暗或模糊背景内容来与inert属性相辅相成。
  • 不要过度使用inert,因为这样做可能会无意中使你页面的大量部分变得不可交互且无法访问。请谨慎使用它,仅在必要时管理用户焦点和交互。
  • 在动态添加和移除inert属性时,请确保在不再需要时正确移除它,以便用户可以重新访问之前被禁用的内容。

15.aria-live属性

你可以使用aria-live属性来通知辅助技术关于网页上动态内容的变化。当aria-live应用于某个元素时,如果该元素内的内容被更新,屏幕阅读器会收到提醒,从而确保用户在页面初次加载后能够得知发生的重要变化。

此属性对于动态更新的内容非常有用,如通知、警报、聊天消息或股票价格等。它确保了用户能够意识到那些可能未被注意到的变化。

aria-live可能的值

aria-live属性主要有三个值:off、polite和assertive

  • off:默认值,表示对该元素的更新不会被屏幕阅读器声明
  • polite:表示屏幕阅读器会声明更新,但会等待用户完成当前任务或阅读完其他内容后再进行。这确保了更新不会打断用户的当前活动。

以下是一个示例,其中每条新消息都被添加到具有aria-live="polite"属性的#messages容器中。屏幕阅读器将在用户完成当前活动后宣布新消息。

<div id="chat-window">
 <div id="messages" aria-live="polite">
 <!-- Existing messages are here -->
 <div>John: Hello!</div>
 <div>You: Hi there!</div>
 </div>
</div>
<button onclick="addMessage()">Send Message</button>
<script>
function addMessage() {
 const newMessage = document.createElement('div');
 newMessage.textContent = 'Alice: How are you?';
 document.getElementById('messages').appendChild(newMessage);
}
</script>
  • assertive:更新将立即声明,打断屏幕阅读器当前正在声明的任何内容。对于需要用户立即注意的重要或关键信息,请使用此选项。

在下面的示例中,股票价格的更新被放置在一个具有aria-live="assertive"属性的容器中。

<div id="stock-ticker" aria-live="assertive">
 <!-- Initial stock prices -->
 <div id="stock1">Stock A: $100</div>
 <div id="stock2">Stock B: $150</div>
</div>

<button onclick="updateStockPrices()">Update Prices</button>

<script>
function updateStockPrices() {
 document.getElementById('stock1').textContent = 'Stock A: $95';
 document.getElementById('stock2').textContent = 'Stock B: $155';
}
</script>

使用aria-live的最佳实践

  • 对于非关键更新,请使用aria-live="polite"以避免干扰用户体验。将aria-live="assertive"保留给需要立即注意的紧急更新,如严重错误或安全警告。
  • 请注意你在页面上使用aria-live元素的频率。过度使用它可能会给依赖屏幕阅读器的用户带来过度刺激的体验,因为他们可能会被频繁的公告所淹没。
  • 不要在不需要公告的内容上使用aria-live,也不要在已经以另一种方式传达给用户的内容上使用它。
  • aria-live对于动态更新的内容特别有用,如实时体育比分、突发新闻或聊天应用程序。请确保用户能够随时了解重要更新。

16.aria-roledescription属性

你可以使用aria-roledescription为元素的角色提供人类可读、本地化的描述。它覆盖屏幕阅读器的隐式或显式role值,并允许开发人员为复杂或非传统的用户界面组件创建更直观和上下文特定的描述,这些组件可能没有标准的角色名称。

你可以借助它更清晰地阐释元素的用途或者功能。

在下面的示例当中,屏幕阅读器会将其声明为“书签按钮”,而非仅仅是“按钮”。

<button role="button" aria-roledescription="Bookmark Button">
 <span aria-hidden="true">⭐</span> Save this page
</button>

你还可以使用它来支持国际化,例如提供不同语言的角色描述。

<button role="button" aria-roledescription="Search Button" lang="en">
 <span aria-hidden="true">��</span> Search
</button>

<button role="button" aria-roledescription="Botón de busqueda" lang="es">
 <span aria-hidden="true">��</span> Buscar
</button>

<button role="button" aria-roledescription="Bouton de recherche" lang="fr">
 <span aria-hidden="true">��</span> Recherche
</button>

使用aria-roledescription的最佳实践

  • 仅当标准角色不能充分描述元素的用途时,才使用 aria-roledescription。
  • 描述应简短、清晰,并与元素的功能直接相关。避免使用行话或过于技术性的语言。
  • aria-roledescription应与适当的 ARIA 角色一起使用,而不是作为替代。该role提供基本上下文(如 “button” 或 “listbox”),而描述则增加了清晰度。
  • 如果你的应用程序支持多种语言,请确保 aria-roledescription 值已本地化以匹配用户的语言首选项。这有助于提供一致且易于理解的体验。
  • 确保 aria-roledescription 不与其他 ARIA 属性或元素标签重复或冲突。它应该补充而不是重复已经提供的信息。

17.aria-atomic属性

你可以使用 aria-atomic 属性来控制辅助技术如何宣布对元素的更新。当 aria-atomic 设置为 true 时,它表示当元素内发生更改时,应将元素的整个内容视为一个单元,并由屏幕阅读器完整宣布(而不是仅宣布更改的部分)。

如果对元素部分的更新可能会使整体上下文不清晰,aria-atomic 会提供帮助,提供元素内容的完整公告,让用户全面了解上下文。

它通常与 aria-live 结合使用。aria-live 决定如何宣布更新(礼貌或自信),而 aria-atomic 控制是读取整个内容还是仅读取更改。

<div id="news-ticker" role="region" aria-live="polite" aria-atomic="true">
 Breaking News: Major storm expected this weekend.
</div>
<button onclick="updateHeadline()">Update Headline</button>
<script>
function updateHeadline() {
 document.getElementById('news-ticker').innerText = 'Breaking News: Stock market hits record high!';
}</script>

使用aria-atomic的最佳实践

  • 仅将 aria-atomic=“true” 应用于完整更新公告对于理解上下文至关重要的元素
  • 使用 aria-atomic=“true” 时,请确保元素中的内容为用户提供一致且完整的上下文
  • 将 aria-atomic 与 aria-live 结合使用,以指定应如何宣布更新。这可确保以适当的方式公布更新,并提供完整的上下文

结论

了解和有效使用HTML属性以提高可访问性对于创建包容性的网络体验至关重要。通过了解并适当使用这些属性,你可以确保你的应用程序为所有访问者提供出色的用户体验。

资源

非常感谢你的阅读,我希望本指南能帮助你创建更易于访问的 Web 内容。

译者介绍

刘涛,51CTO社区编辑,某大型央企系统上线检测管控负责人。

原文标题:How to Use HTML Attributes to Make Your Websites and Apps More Accessible,作者:Elizabeth Lola

责任编辑:华轩 来源: 51CTO
相关推荐

2011-11-03 09:41:35

Android签名安全性

2022-02-24 23:56:45

Web应用程序工具

2023-09-25 12:18:48

2020-03-31 10:19:14

网络安全IT安全漏洞

2012-03-20 10:28:43

2009-07-14 12:58:49

AWT和Swing

2010-07-20 11:35:41

避免SQL Serve

2024-02-26 00:01:01

RedisGolang应用程序

2010-09-13 10:39:43

CSSCSS文件

2013-11-19 15:35:01

2021-05-10 10:50:53

NginxIPLinux

2013-09-24 09:49:23

下一代防火墙NGFW

2012-12-14 09:35:03

私有云应用程序可移植性OpenStack

2022-06-22 09:00:00

安全编程语言工具

2012-05-24 15:49:35

HTML5

2023-07-26 16:20:36

云原生云计算

2018-12-28 14:10:57

开发工具 移动应用

2018-07-18 16:12:25

Windows 10Windows应用程序

2021-05-27 08:15:05

CSS CSS prefer技巧

2024-06-11 08:00:00

.NET开发网络攻击
点赞
收藏

51CTO技术栈公众号