何时使用role="button",何时不使用?

11

在可访问性方面,有人能否向我描述一下对于屏幕阅读器和键盘用户来说,<button><a> 的区别? 据我所知,键盘用户可以使用 ENTERSPACE 来激活按钮,而只有用 ENTER 来激活锚标签。在单页应用程序中,我觉得这些元素的角色有点混淆,我不确定两者之间的界限在哪里。

看起来像链接的按钮

在我的应用程序中,我对链接有一个通用样式,这个样式的类名简单地为 .link

在第一个示例中,我有一个按钮,它具有一个在同一页上执行操作的 onclick 处理程序,因此我使用了一个按钮元素。 但是,它的样式上看起来像一个链接。

<button class="link" onclick={(e) => console.log('Do the thing')}>This is a link</button>
如果角色颠倒,链接的行为像传统的锚点一样,其中路由会因为被点击而改变,我会这样做:

结果:如果角色颠倒,链接的行为像传统的锚点一样,其中路由会因为被点击而改变,我会这样做:

<a class="link" href="/route/change">This is a link</a>
尽管由于应用的类别,这两个元素看起来相同,但是是否应该将role="button" 应用于锚标签示例以使其行为像一个按钮,即使它的样式像一个链接?对于具有辅助功能需要的用户,在整个应用程序中保持这些样式化元素之间的一致性更好,还是基于元素的应用而不考虑其样式,交换哪个元素得到应用角色更好?

旁边的两个“按钮”

追加第一个问题。如果<a> 标记的定义是将您移动到不同的页面/锚点,则执行不同任务的两个并排按钮都应被视为按钮。

以以下示例为例,确认按钮在同一页面上执行操作,而取消按钮则将您路由回以前的页面。

button example

代码看起来像这样:

<button onclick={() => console.log('do a thing'}>Confirm</button>
<a href="/home">Cancel</a>

来自 MDNrole="button"定义如下:

应该将按钮角色用于可点击的元素,这些元素在用户激活时会触发响应。添加role="button"将使元素显示为屏幕阅读器的按钮控件。可以将此角色与aria-pressed属性结合使用以创建切换按钮。

即使取消按钮从技术上来说不符合角色定义的方式,它是否应用了按钮角色?

关闭

是否有更简明的指南说明何时应该使用和不使用这些角色?如果具有相同样式的所有/任何链接与


一个按钮已经具有按钮角色,因为它是一个按钮。这个想法是,如果真的必要,你可以让其他元素在使用 AT 的人看起来像按钮。这在你发布的 MDN 引用中已经暗示了。我不确定为什么你想将其应用于锚点。 - isherwood
没错,但是对于我提到的链接表现为按钮或按钮表现为链接的情况呢?是否有明确的定义来确定何时应该使用其中之一,还是由自己决定?你不能从<button>元素中删除角色,因为它已经被暗示了,但它看起来像一个链接。 - James Ives
如果锚点的行为与按钮相同,为什么要使用锚点?使用按钮并相应地进行样式设计。例如,Bootstrap为此类情况提供了CSS。当锚点的行为像锚点时,为什么要让用户认为它是一个按钮呢?我不明白这种情况。 - isherwood
1
样式应该决定元素的角色吗?如果我有一个看起来像按钮的东西,但是将你锚定到另一个页面,即使在幕后它不是一个按钮,它是否应该具有role="button"?如果一个功能按钮看起来像链接,那么在整个应用程序中应该具有相同一致的角色,即如果有一些具有相同样式的按钮元素,则所有相同外观的“链接”都应该具有按钮角色。我没有使用Bootstrap,但是您提供的示例并没有说明屏幕阅读器如何查看元���或期望的内容。 - James Ives
你的意思是锚点永远不应该扮演按钮的角色吗? - James Ives
显示剩余3条评论
3个回答

8
每当我遇到“按钮 vs 链接”的问题时,我会问自己,这是脚本功能还是导航(内部或外部)?
按钮在网页上激活脚本功能(对话框,展开/折叠 - 区域)。
链接带您转到另一个位置,无论是到不同的页面还是同一页的不同位置。
关于a11y
角色告诉屏幕阅读器和其他辅助技术元素的语义类别,即它的类型。每个元素已经有某种默认角色。button 元素具有隐含的 role="button",img 元素具有隐含的 role="img" 等等。
role="button"
如果使用 button,请勿添加 role(它是隐含的)。
-(添加角色不会导致浏览器提供键盘行为或样式)。尽量使用真正的 button 如果出于样式目的而存在问题,可以使用 role="button"。请确保添加 tabindex="0" 使其能够键盘聚焦,并确保它与 Enter 键和 Spacebar 均可使用,确保它具有适当的禁用、悬停、焦点状态,使用媒体查询在高对比中工作。
不要使用 a role="button":在任何方面都没有意义,它将给您一个块级元素,就像 div 一样,您可以随意设置其样式。记住这个问题,如果是脚本功能,请使用 button 或 div role="button",如果是导航,请使用 a 没有任何角色(根据需要设置样式)。
此外,a 不能禁用,button 可以禁用。
屏幕阅读器有快捷键可以读出所有链接,例如 NVDA 用户可以按:
K - 跳转到下一个链接
INS + F7 列出所有链接、标题
U - 未访问链接快捷键
V - 已访问链接快捷键
我也考虑屏幕阅读器用户在按下 ins+f7 时是否要听到此链接?
编辑:我忘记提到为元素分配角色会覆盖其原生角色。因此,a role="button"不再是一个role="link",不会出现在 INS + f7 列表中,并且由辅助功能 API 它将被视为按钮。

0
在这种情况下,我建议在链接上使用role='button',因为这是用户在此情况下的两个选择之一,并且这两个选择应该以相同的形式出现(即作为两个按钮),这样对于通过屏幕阅读器听到它的用户来说也更方便。
我只是想知道为什么您首先使用链接而不是立即使用按钮来取消选项...

因为取消按钮会将您从当前页面导航到其他页面。虽然在这里不使用按钮的角色似乎更符合语义,但我正在寻找证明哪种方式更好的文档。 - James Ives
你可以在第二个按钮上添加一个 aria-label 属性,告诉用户这个选择会将他/她带离当前页面。 - Johannes

0

解决方案很简单: "如果不是链接,那就是按钮"

  • 链接应该带你去别的地方:另一个页面,页面内的另一个锚点。

  • 链接不会提交表单,也不会执行任何操作。

在你的例子中,“确认”和“取消”是动作:你正在提交你的同意或明确表示你想要取消你的操作。它们应该具有ARIA button角色。

这与“继续”和“返回上一页”不同,后者应该具有link角色。


我不同意这很简单。因为在我的例子中,取消按钮会将您带到另一个页面,而不是提交表单。你所说的并不完全符合我提供的例子。它执行了一个操作,但该操作是锚标签的操作。 - James Ives
跟进一下,有没有任何支持这个的文档或规范?我听到了很多不同的意见,但似乎没有一个“正确”的答案。 - James Ives
您的访问者不需要知道或关心底层技术(buttonforma[href])。重要的是要可预测:我在一个form中;我期望按钮提交或取消,而不是链接。 - Adam
但是,如果将其作为锚点而不是按钮,是否会对辅助设备造成问题,因为用户由于它是锚点而获得了额外的功能?如果错误地将其作为按钮,则用户可能不知道这将使他们离开表单? - James Ives

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接