为什么、如何以及何时使用语义 HTML 和 ARIA

Avatar of Adam Silver
Adam Silver

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 价值 200 美元的免费信用额度!

语义 HTML 和可访问的富互联网应用 (ARIA) 有助于创建对所有人都有效的界面,以最有效、稳健和简单的方式。它们为您的内容添加了必要的含义,使 Web 浏览器、搜索引擎、屏幕阅读器、RSS 阅读器以及最终的用户能够理解它。

然而,许多人仍然不使用它们。我想知道为什么,所以我做了一个 Twitter 调查。人们给出的最常见原因是对使用语义 HTML 和 ARIA 的好处缺乏了解和理解。

让我们回顾一下使用 HTML 和 ARIA 的好处,为什么从语义 HTML 开始是最佳选择,以及为什么 ARIA 应该作为最后的手段。

从原始文本开始

HTML 文档的 <body> 元素包含用户在页面上看到的主要内容。如果将内容放在正文中而不添加任何其他元素,浏览器将无法区分不同类型的文本,例如段落和标题。

<body>
A Study of Butterflies

Butterflies are little bugs with cute wings.

Butterfly Habitats

Butterflies live in flower houses and hang out at dank coffeeshops.
</body>

如果浏览器无法区分文本片段,它就不能以有意义的方式将这些文本呈现给用户。这意味着

  • 我们无法将标题与段落区分开来。
  • 搜索引擎难以解释内容,这意味着它可能排名很低,用户难以找到它。
  • 屏幕阅读器和其他辅助技术无法正确地向用户传达信息。

更不用说,从视觉上看,这有点笨拙。

A screenshot of the HTML rendered on the front end, which displays as a single line of text.

使用 HTML 添加一些结构

为了提供一些结构,我们可以将这里文本行包装在 div 中,如下所示

<div>A Study of Butterflies.</div>
<div>Butterflies are little bugs with cute wings.</div>
<div>Butterfly Habitats</div>
<div>Butterflies live in flower houses and hang out at dank coffeeshops.</div>

这稍微好一些,因为每个文本片段都显示在浏览器中的独立行上,而不是一行长长的文本。

A screenshot of the HTML rendered on the front-end showing the content on four lines, one for each div.

但仍然缺乏明显的含义。

哪些是标题,哪些是段落?很难辨认,辅助技术也无法确定。这是因为标题和段落被包装在 div 中,而 div 本身没有意义。在这个例子中,浏览器、CSS、搜索引擎和屏幕阅读器仍然无法理解。

用样式传达含义

我们可以为 div 添加样式,因为它们可以用 CSS 作为目标。这使我们能够改进视觉外观,从而提供意义、上下文和层次结构。

查看 CodePen 上的
非语义 HTML 演示
,作者 Geoff Graham (@geoffgraham)
CodePen 上。

这里,CSS 以第一个和第三个 div 为目标,以应用标题样式。这是不可维护的,因为之后添加的另一个段落将被样式化成标题。

我们可以为每个 div 提供一个唯一的属性,例如 ID 或类名,以获得更多样式控制,如下所示

<div class="heading1">A Study of Butterflies</div>
<div class="paragraph">Butterflies are little bugs with cute wings.</div>
<div class="heading2">Butterfly Habitats</div>
<div class="paragraph">Butterflies live in flower houses and hang out at dank coffeeshops.</div>

在我的在线书籍 MaintainableCSS 中,我解释了为什么你应该使用 类而不是 ID 进行样式设置

现在,我们可以使用 CSS 以不同的元素为目标,如下所示

.heading1 { /* styles here */ }
.paragraph { /* styles here */ }
.heading2 { /* styles here */ }

虽然这种方法稍微好一些,但它只为视力正常的用户传达含义。它不会为搜索引擎、RSS 阅读器和屏幕阅读器提供意义。换句话说,它不具有语义性,因此可访问性也不高。

介绍语义 HTML

HTML 提供了许多旨在为内容赋予意义的元素,包括用于标题和段落的元素。因此,我们可以使用预定义的 HTML 元素,而不是依赖于由开发人员命名的带有类的 div。

<h1>A Study of Butterflies</h1>
<p>Butterflies are little bugs with cute wings.</p>
<h2>Butterfly Habitats</h2>
<p>Butterflies live in flower houses and hang out at dank coffeeshops.</p>

好多了!使用这样的语义 HTML,内容将从浏览器继承 默认样式(也称为 用户代理)。我们甚至可以使用其他语义 HTML 元素,例如 <b>,它告诉浏览器“引起注意”,使文本变为粗体。

A screenshot of the HTML rendered on the front end showing the content with a clearer hierarchy of a Heading 1, paragraph, Heading 2 and paragraph, thanks to semantic HTML.

最重要的是,使用语义 HTML 还意味着

  • 我们可以使用 CSS 添加我们自己的样式。
  • 搜索引擎可以索引内容,使其排名足够高,以便用户可以找到它。
  • RSS 阅读器可以适当地解析和设置元素的样式。
  • 屏幕阅读器和其他辅助技术可以正确地向用户传达元素。

虽然在这些简短的例子中并不十分重要,但代码也更加简洁,这在考虑整个网站时会产生很大影响。

语义 HTML 是基于标准的,并且稳定。这意味着未来的任何 HTML 处理器都将能够理解它,并将其正确地呈现给用户。如果需要进行更改,它也会帮助后续的代码作者。

语义 HTML 的其他好处

除了我们已经介绍过的优点之外,一些浏览器还免费为语义 HTML 添加了有用的增强功能。

例如,使用 HTML 电话输入 (<input type="tel">) 将在某些移动浏览器上为用户提供电话专用键盘。

将表单输入标识为电话字段将在 iOS 上生成电话专用键盘。但请注意,它只用于电话号码,不适用于任何其他号码,例如信用卡号码。

其他浏览器允许用户切换到页面的简化视图,例如 Safari 的阅读器模式。如果没有语义 HTML,阅读器模式将生成类似于我们开始使用的一行文本字符串的内容。但是,通过使用语义 HTML,我们可以在没有额外的样式的情况下获得干净的阅读体验。

我的个人网站上的“关于”页面使用 Safari 的阅读器模式查看,比较了非语义 HTML(左侧)和语义 HTML(右侧)。

您可以在 Mandy Michael 的文章中阅读更多关于此内容的信息,为 Safari 阅读器模式和其他阅读应用程序构建网站

ARIA 何时能改善体验

与语义 HTML 一样,ARIA 是 W3 标准,它有助于使界面更方便使用屏幕阅读器和其他辅助技术来使用内容的人员访问。

错误消息就是一个很好的例子。如果用户未填写必填的表单字段,错误的 HTML 可能如下所示

<label for="first-name">First name</label>
<span>Enter your first name</span> 
<input type="text" name="first-name" id="first-name">

视力正常的用户将能够在字段上方看到错误。但是,当屏幕阅读器将焦点放在输入字段上时,不会宣布错误,因为错误消息没有与输入字段关联。

可以使用 ARIA 将错误与输入字段关联,如下所示

<label for="first-name">First name</label>
<span id="first-name-error">Enter your first name</span>
<input type="text" name="first-name" id="first-name" aria-describedby="first-name-error">

现在,当输入字段处于焦点时,会宣布错误消息。

将 ARIA 和 JavaScript 结合使用

当涉及 JavaScript 时,ARIA 最有用。JavaScript 通常需要创建更复杂和动态的交互,例如在不刷新页面的情况下隐藏、显示和更改元素。例如,切换菜单、手风琴、选项卡、自动完成、可排序表格、加载内容并保存、发送或获取数据。以这种方式增强界面通常会破坏屏幕阅读器用户的体验。

以一个按钮为例,当选择它时,它会显示其他内容。在原始状态下,视力正常的用户最初会看到一个按钮,没有内容,当单击按钮时,内容会出现。

然而,有视觉障碍的屏幕阅读器用户通常依赖语音提示来浏览界面。但是,当屏幕阅读器将焦点放在按钮上时,没有任何提示可以告诉它内容是否当前可见,是否需要读取。

可以向按钮添加 aria-expanded 属性,JavaScript 可以将它的值在 true(内容正在显示)和 false(内容已隐藏)之间切换。这有助于满足 包容性设计原则 #1,提供类似的体验,让屏幕阅读器用户能够使用。

<button aria-expanded="false">Toggle content</button>
<div hidden>Some content</div>

尽量避免使用 ARIA 修复语义不正确的 HTML

ARIA 属性可用于使语义不正确的 HTML 对屏幕阅读器用户更易访问。例如,开发人员在为多个浏览器样式化本机复选框时可能会遇到困难,因此他们可能决定使用 div 和一些 JavaScript 来模拟一个复选框。

我们可以添加一个 role 属性(复选框)让 div 向屏幕阅读器用户标识自己为一个复选框

<div role="checkbox"></div>

我们还必须使用 aria-checked 属性来指示复选框是否选中,如下所示

<div role="checkbox" aria-checked="false"></div>

但是,这还不够让它像复选框一样工作,因为 div 与 <input type="checkbox"> 不同,它们无法通过键盘获得焦点。我们可以通过添加 tabindex="0" 来使它们可获得焦点

<div role="checkbox" aria-checked="false" tabindex="0"></div>

但即使这样,真正的复选框在作为表单的一部分提交时,也会发送其值。由于这不是真正的复选框,因此它不会在不使用 JavaScript 的情况下提交其值。

而且如果这还不够,用户可以通过按 Space 键来选中或取消选中真正的复选框。当复选框处于焦点状态时,可以通过按 Enter 键提交复选框所属的表单。但是,div 版本的复选框如果没有更多 JavaScript,将无法实现此功能。

这不仅需要更多工作和更多代码,而且这种方法实际上只适用于那些使用理解这些特定 ARIA 属性的技术的人。这需要付出很多努力,写很多代码,也会带来很多问题,而如果我们使用语义 HTML,则可以完全避免这些问题。

<input type="checkbox">

不可否认,ARIA 在某些情况下很有用,但是尽可能从语义化的、可访问的 HTML 开始会更加简单,也更可靠。这就是为什么 ARIA 的第一条规则是不使用它

结论

包容性设计是为最广泛的用户提供最佳体验。语义 HTML 有助于技术以及用户理解网络上的内容。一些浏览器和设备提供的增强功能意味着用户可以获得更好的体验。

当语义 HTML 本身不足时,ARIA 可以为辅助技术用户提供更多上下文信息,但请谨慎使用。它不能完全解决语义不正确的标记问题,而且可能变得很复杂,就像我们在最后一个示例中看到的那样。

简而言之,要付出努力让内容更具包容性。这对您和网络来说都是胜利。