带有角色按钮的锚链接内图像的可访问性:可点击元素必须是可聚焦的并且应该具有交互式语义

Posted

技术标签:

【中文标题】带有角色按钮的锚链接内图像的可访问性:可点击元素必须是可聚焦的并且应该具有交互式语义【英文标题】:accessibility for image inside an anchor link with role button: Clickable elements must be focusable and should have interactive semantics 【发布时间】:2022-01-23 07:41:07 【问题描述】:

我有以下标记:

<li class="remove-filter-key-list-item" data-id="this.id">
  <a
    href="#"
    class="remove-filter-key-button flx jst-cntr"
    role="button"
    tabindex=0
  >
    <img
      class="remove-filter-key-list-icon"
      src="this.icon"
      
    />
    <span
      class="remove-filter-key-list-title"
    >this.statusText</span>
  </a>
</li>

在 firefox 可访问性检查器中触发 this error:

据我所知,该链接在这两个事件上都需要一个 onclick 侦听器、一个 keydown 侦听器、一个选项卡索引和一个prevent default。我已经尝试添加这些,但错误仍然存​​在。 Firefox 似乎专注于锚链接内的图像,而不是链接本身,这是可点击的东西。

我在 javascript 文件中添加监听器(我没有也不能在 html 中内联添加它们),如下所示:

function addStatusFilterListener(el) 
  el.addEventListener("click", onStatusFilterToggle);
  el.addEventListener("keydown", (e) => 
    e.preventDefault();
    if (e.keycode === 32) 
      //if spacebar
      onStatusFilterToggle(e);
    
  );

这似乎不起作用 - 空格键滚动页面,我的事件没有被触发,似乎可访问性检查器正在寻找包含的 img 标记上的事件。解决这些问题的正确方法是什么?

【问题讨论】:

【参考方案1】:

为了省去很多变通方法和麻烦,最直接的解决方案是将图像包裹在一个按钮中,而不是试图让锚点表现得像一个按钮。

这意味着您不必担心不同的处理程序等,因为按钮上的 click 事件处理程序具有内置的所有行为!

在以下示例中,我将您的代码更改为使用&lt;button&gt;,并添加了data-id,以提醒单击了哪个项目。

您将看到您可以使用 EnterSpace 来激活项目以及单击鼠标!

const removeBtn = document.querySelectorAll('.remove-filter-key-button');

removeBtn.forEach((element)  => 
   element.addEventListener('click', onStatusFilterToggle);
);

function onStatusFilterToggle(e)
  let el = e.currentTarget;  
  let itemID = el.getAttribute('data-id');
  alert("you pressed item: " + itemID);
button
   border: 0px;
   background: transparent;

button:hover
   cursor: pointer;
   opacity: 0.9;
<button class="remove-filter-key-button flx jst-cntr" data-id="1">
    <img
      class="remove-filter-key-list-icon"
      src="https://picsum.photos/100/100"
      
    /><br>
    <span
      class="remove-filter-key-list-title"
    >Current Status</span>
  </button>
  <button class="remove-filter-key-button flx jst-cntr"  data-id="2">
    <img
      class="remove-filter-key-list-icon"
      src="https://picsum.photos/100/100"
      
    /><br>
    <span
      class="remove-filter-key-list-title"
    >Current Status</span>
  </button>

【讨论】:

只是关于这个解决方案的一个注释——当我实现这个时,按钮内的图像仍然被标记为需要可聚焦并具有交互语义。我可以通过为图像(图标)提供aria-hidden 属性来抑制该错误。另一种解决方案(在这里并不容易,因为按钮内有图像和文本),将图标设置为按钮的背景图像。 您可以通过将alt 属性设置为"" (alt="") 来实现相同的效果,因为这有效地隐藏了辅助技术的图像(如果它只是一个图标,这可能是正确的你有状态文本)。然而,无论如何这是一个误报,因为图像不需要可聚焦,所以我不确定是什么导致检查器拾取它(你没有任何机会在图像上有一个流浪的click 处理程序因为这是我能想到的唯一会导致它提出这个建议的事情?)。【参考方案2】:

关于您的代码,我想说的是:

tabindex=0 是不必要的,因为默认情况下链接是可聚焦的。 键盘处理程序是不必要的,因为按下回车已经触发了链接和/或点击处理程序。这甚至可能是危险的,因为您使界面与用户对链接或按钮的期望不同。 将tabindex=0 添加到&lt;img/&gt;&lt;span&gt; 或链接内的任何内容都会造成麻烦;嵌套的可聚焦或可点击元素会造成混乱,因为用户无法很好地理解它们,并且触发的实际事件定义不明确和/或难以处理。 图片有一个替代文字,所以从可访问性来说,你看起来都很好

【讨论】:

以上是关于带有角色按钮的锚链接内图像的可访问性:可点击元素必须是可聚焦的并且应该具有交互式语义的主要内容,如果未能解决你的问题,请参考以下文章

按钮SwiftUi内图像的背景颜色问题

角度 5 中动态元素的可访问性

在 MVC 中处理多个角色 - 基于操作的可访问性

tablist 角色的可访问性问题

jQuery - 使用锚链接将元素滚动到屏幕中间而不是顶部

UIStackView 可访问性 - 在默认的可访问元素中插入可访问性视图?