1

在网页无障碍领域,最具争议的问题之一是,在创建某些类型的交互元素时,应该使用按钮还是链接。为什么这个问题如此有争议?多年来,无障碍专家已经无数次回答了这个问题。同时,还有大量的参考文献提供了这个问题的答案。

答案很简单,只有在没有考虑到为什么链接和按钮的外观和行为完全不同的情况下,才会引起争议。

按钮和链接的行为有何不同?

首先,了解按钮和链接的区别很重要。我曾看到有人错误地将它们混为一谈,过度简化为 "执行动作 "的元素。虽然它们都能让用户执行不同的操作,但这并不意味着它们是相同的元素。

我们通过阅读一些 HTML Living StandardWAI-ARIA 1.2 的内容来回答这个关于行为差异的问题。

注意:本文仅讨论 HTML <button><a> 元素。

关于链接

HTML Living Standard 有一个专门讨论链接的部分。以下是该文档提供的释义:

链接是一个概念性结构,代表两个资源之间的连接。

它还指出,链接有两种类型:外部资源链接和超链接

我们分别举例说明。

外部资源链接

指向外部资源的链接是指当前网站之外的资源。可以通过设置 rel 属性为 "external" 来标记这些链接,然后还可以使用像 a[rel="external"] 这样的 CSS 属性选择器对它们应用独特的样式。例如,您可能选择在每个 rel="external" 的链接后面附加文本 "(外部链接)"。这可以通过以下 CSS 实现:

a[rel="external"]::after {
  content: " (external link)";
}

相关概念:提前警告用户上下文变化,以尽量减少混淆

还可以对带有 target="_blank" 的链接应用特殊样式。在以下示例中,文本“(在新标签页中打开)”被添加到链接中,以警告用户激活链接时会发生多个上下文变化。

a[target="_blank"]::after {
  content: " (opens in new tab)";
}

这与 Success Criterion 3.2.5: Change on Request 有关,该标准指出:

只有在用户提出要求时才会更改上下文,或者有一种机制可以关闭这种更改。

出于许多原因,提醒用户某个操作会导致上下文变化非常重要。一些用户可能因为认知限制或视觉、阅读或智力障碍而无法察觉到上下文的变化。对于运动能力有限的用户来说,意外和不必要的上下文变化会导致他们需要付出额外努力才能回到原来的状态。

超链接

超链接是指向当前网站内资源的链接。下面是一些例子:

  • 链接到当前页面上的另一个位置,例如目录有一个链接到标题元素的链接
  • 链接到网站的另一个页面,例如链接到另一个网站的相关博文
  • 可下载文件的链接,这些文件将在以后使用,而不是立即使用

根据 HTML Living Standard,<a> 元素的 rel 属性有多个值可用于指定元素为超链接:alternate、author、bookmark、help、license、next、prev、search 和 tag。

我列出这长长的值列表并不是因为我认为了解每一个都很重要。这样做是为了更明显地展示原生 <a> 元素所处理的大量功能。你可能听说过,当你想将 <button> 元素变成链接时,可以应用 role="link",但这远远不够。

当想渲染一个链接时,不使用原生的 <a> 元素会导致大量功能丧失,而我们讨论的这一个属性只是触及了表面。在这里,ARIA 的第一条规则非常重要:

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

ink ARIA 角色

在定义链接方面,我们还有一个话题要讨论,那就是 link 角色。 link<a> 元素的默认角色。下面是该角色的定义方式:

对内部或外部资源的交互式引用,激活后可使用户代理导航到该资源。

还有一条注释写道:

如果按下链接会触发操作,但不会改变浏览器焦点或页面位置,建议作者考虑使用按钮角色而不是链接角色。

根据我们迄今为止所了解的所有信息,我认为我们可以对链接做出如下定义:连接两个资源的元素,激活后可执行以下操作之一:下载链接资源、将浏览器焦点切换到页面的另一部分或将浏览器位置切换到另一个页面

关于按钮

HTML Living Standard 并没有像对链接那样为我们提供太多关于按钮的非技术信息,因此我将依赖 MDN Web 文档和 WAI-ARIA 1.2 规范来进行定义。

<button> 元素

MDN Web Docs 对按钮元素的定义如下

<button> HTML 元素是一种交互式元素,用户可以用鼠标、键盘、手指、语音指令或其他辅助技术激活它。一旦激活,它就会执行一个可编程的操作,如提交表单或打开对话框。

按钮元素接受的一长串属性:

  • autofocus 自动对焦
  • autocomplete 自动完成
  • disabled 禁用
  • form 组成
  • formaction 行动
  • formenctype 表单类型
  • formmethod 方法
  • formnovalidate
  • formtarget 表单目标
  • name 名字
  • type
  • value

这是一个很大的功能。该列表还说明了为什么混合匹配 <a><button> 元素不是一个好主意。仅仅将 role="button" 应用于 <a> 元素还不足以使锚元素与按钮元素的本地实现相匹配。事实上,如果不使用辅助技术,仅仅更改 role 并不能改变元素的外观或行为。

button ARIA 角色

WAI-ARIA 1.2 规范指出, button 的作用是:

点击或按下时允许用户触发操作的输入。按钮主要用于不连续的操作。将按钮的外观标准化,可增强用户将部件识别为按钮的能力。

这就是说,按钮通常一次只用于执行一个动作。它还指出,用户可以从按钮的标准化外观中获益,从而识别出按钮是一种交互式元素。

button 角色支持一种 ARIA 状态,而 link 角色不支持这种状态。这个状态就是 aria-pressed 。它传达了切换按钮的 "按下"状态。这并不是 <a> 元素的特质。这是另一个例子,说明按钮和链接之间的差别有多大。

Button WAI-ARIA小工具

ARIA 创作实践指南 (APG) 是学习无障碍语义和键盘界面的有用资源。它有几个常用小工具的示例。它还包括有关常见做法的资源。

其中一个部件示例是按钮部件。在定义了该 widget 并命名了另外两种支持的按钮类型(切换和菜单)后,它指出了区分链接和按钮的重要性:

按钮执行的操作类型与链接的功能截然不同。重要的是,窗口小部件的外观和作用必须与其提供的功能相匹配。

它还指出,有时链接具有按钮的视觉风格,但它说还有一个更好的解决方案:调整设计。

然而,元素有时具有链接的视觉样式,但执行按钮的动作。在这种情况下,为元素赋予按钮角色有助于辅助技术用户理解元素的功能。但更好的解决方案是调整视觉设计,使其与功能和 ARIA 角色相匹配。

比较链接和按钮

现在,我们应该对链接和按钮的不同之处有了一定的了解。下面再列举几个不同之处的例子:

  • 按钮和链接的鼠标指针是不同的, <a> 元素悬停时的鼠标光标是 pointer 。而对于 <button> 元素,则是默认/自动光标
  • 即使本地 <button> 的角色是 link ,也始终可以通过键盘访问。本地 <a> 只有在定义了 href 属性的情况下才能通过键盘访问,即使其角色为 button 也是如此。这意味着,如果您决定不将本地元素用于其预期目的,还需要做额外的工作来使键盘界面正常工作。
  • 用户代理和辅助技术可提供包含不同类型元素的导航列表。Mac 上的 VoiceOver 旋转器就是一个例子。按钮列在 "表单控件 "下,链接列在 "链接 "下。如果一个元素的编码方式无法被辅助技术识别,那么用户就无法正常浏览页面。这并不是屏幕阅读器的失败。本地元素已经兼容,所以请使用它们!
  • 用户代理和辅助技术还提供了与不同类型元素交互的命令和手势。不使用本地元素会干扰这些功能,导致用户感到困惑和沮丧。这并不是屏幕阅读器的失败。本地元素已经兼容,所以请使用它们!

还有多少用户代理或辅助技术功能被编码不良的元素破坏?我不知道。你想测试每一个元素并找出答案吗?我很怀疑。使用本地 HTML 元素即可!

请记住使用 ARIA 的第一条规则:

如果可以使用已内置所需语义和行为的本地 HTML 元素或属性,而不是重新利用一个元素并添加 ARIA 角色、状态或属性使其可访问,那么就这样做吧。

不要忘记使用 ARIA 的第二条规则:

除非确有必要,否则不要改变本地语义。

为什么按钮和链接的样式不同

有四项无障碍原则指导我们必须如何构建网络和内容。可以用缩写词 POUR 来记住它们:信息和界面必须是可感知的、可操作的、可理解的和稳健的

按钮和链接的外观与无障碍环境的四项原则有什么关系呢

  • 在用户操作界面之前,他们必须能够感知界面中哪些元素是交互式的。
  • 为了让用户在操作界面之前做出明智的决定,界面必须易于理解。
  • 为了让用户能在多种条件和环境下操作界面,界面必须坚固耐用。

那么答案是什么呢?

当你需要连接两个资源,且元素被激活时需要发生以下情况之一时,请使用锚元素:

  • 下载链接资源
  • 将浏览器焦点移至页面的其他部分、
  • 将浏览器定位到另一个页面

当需要让用户执行可编程操作(如提交表单或打开对话框)时,可使用按钮元素。

交流

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


王大冶
68.1k 声望105k 粉丝