让屏幕阅读器忽略某个部分,但阅读其重点内容

时间:2019-04-19 16:34:39

标签: html accessibility wai-aria screen-readers

我有一些看起来或多或少像这样的代码(例如,减少了):

html {
  background: #eee;
}

section {
  border-radius: 4px;
  border: 1px solid #ccc;
  background: #fff;
  margin: 1em;
  padding: 1em;
}

[tabindex]:focus {
  outline: 1px dashed blue;
}
<section tabindex="0">
  <h1>
    Section 1
  </h1>
  <p>
    This section will be highlighted but it won't go inside as 
    nothing inside has tabindex. I don't want it to be read at all.
  </p>
</section>

<section tabindex="0">
  <h1>
    Section 2
  </h1>
  <p>
    This section will be highlighted and there is an element inside with 
    tabindex. I don't want the section to be read, but I want to read
    the focusable elements when they are focused.
  </p>
  <p tabindex="0">
    For example: this paragraph has tabindex. It should be read when focused.
  </p>
</section>

因为有tabindex,所以获得焦点时会突出显示不同的部分。该突出显示可轻松识别用户在任何给定时刻所在的部分。

在每个部分的内部可能有任何内容:文本,html代码,可聚焦的内容(因为它具有tabindex或具有交互元素)。这是一个Web组件,我无法控制内部内容。

我们有屏幕阅读器用户和弱视用户,他们都使用键盘进行导航,对于后者,我们希望帮助确定他们位于哪个部分(在具有多个部分/卡片的页面中),而不会对屏幕阅读器用户。

当该部分突出显示时,我希望它只是图形化的(带有轮廓),但是我不希望屏幕阅读器读取其内容,因为如果内部有任何交互式/可聚焦的内容,它将被阅读两次,不想重复。

例如:使用诸如ChromeVox或VoiceOver之类的屏幕阅读器,当按下标签时,第一部分将被概述,并且听起来像这样:

  

[Section]第1部分。该部分将突出显示,但不会进入内部,因为其中没有tabindex。我根本不想读它。

再次点击选项卡,第二部分将被概述,听起来类似:

  

[Section]第2部分。该部分将突出显示,并且其中的元素带有tabindex。我不希望阅读本节,但是我想在焦点对准元素时阅读它们。例如:本段具有tabindex。专注时应阅读。

第三次点击选项卡将激活该部分中的最后一段(它具有tabindex),并且屏幕阅读器将显示:

  

例如:本段具有tabindex。专注时应阅读。

这种情况并不理想,因为我们正在重复内容(请记住上面的代码是一个示例,实际上不仅仅如此)。当一个部分获得焦点时,它会被完全读取。当里面的内容获得关注时,它会再次被读取。最后一句话被读了两次:该部分处于活动状态以及自身处于活动状态。

我想要得到以下行为:

  1. 选项卡,第一部分突出显示。什么都没读。
  2. 选项卡,第二部分突出显示。什么都没读。
  3. 选项卡,最后一段被突出显示并被阅读。

我尝试通过不同的方法来实现这种行为:

  • 使用role="presentation" :因此角色语义将不会映射到可访问性API,并且不会被读取...问题在于role="presentation" doesn't apply on focusable elements(例如带有tabindex)。
  • 使用role="none" :它是role="presentation"的同义词,因此以相同的方式失败。
  • 使用aria-label="" :它会忽略空白的aria-label,但仍会读取该部分的全部内容。
  • 使用aria-hidden="true" :通过这种方式,将忽略该节,并且不读取其内容...但是,当它获得焦点时,其可聚焦的内容也将被忽略并且不读取-那就是我想要:

html {
  background: #eee;
}

section {
  border-radius: 4px;
  border: 1px solid #ccc;
  background: #fff;
  margin: 1em;
  padding: 1em;
}

[tabindex]:focus {
  outline: 1px dashed blue;
}
<section tabindex="0" aria-hidden="true">
  <h1>
    Section 1
  </h1>
  <p>
    This section will be highlighted but it won't go inside as 
    nothing inside has tabindex. I don't want it to be read at all.
  </p>
</section>

<section tabindex="0" aria-hidden="true">
  <h1>
    Section 2
  </h1>
  <p>
    This section will be highlighted and there is an element inside with 
    tabindex. I don't want the section to be read, but I want to read
    the focusable elements when they are focused.
  </p>
  <p tabindex="0">
    For example: this paragraph has tabindex. It should be read when focused.
  </p>
</section>

我尝试用div将本节的全部内容包装到aria-hidden="false"中,但是似乎父级的aria-hidden="true"取代了它。

有没有办法实现我想要的?

2 个答案:

答案 0 :(得分:0)

简短答案:停止在所有地方添加tabindex。屏幕阅读器用户可以使用阅读键进行导航,因此,使您的内容具有可聚焦性是没有意义的。

答案 1 :(得分:0)

屏幕阅读器用户不需要tabindex即可使用键盘在文本内导航。

仅交互式元素(按钮,链接,表单元素等)可能具有tabindex。而且,如果您使用本机交互式元素(tabindex a[href]button,...),则不必添加input,仅用于自定义控件({ {1}}。

可聚焦元素不应位于另一个可聚焦元素内。

屏幕阅读器主要具有two navigation mode:浏览/阅读模式(通常使用箭头键)和焦点/表单模式(使用<div role="button" tabindex="0">click here</div>键)。屏幕阅读器用户绝不会使用tab键来阅读非交互式文本。

您也不需要在当前阅读的文本中添加大纲,因为屏幕阅读器会在浏览模式下自动完成。