使屏幕 reader 忽略一个部分但阅读其可聚焦的内容
Make screen reader ignore a section but read its focusable content
我有一些代码看起来或多或少像这样(例如减少):
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 组件,我无法控制其中的内容。
我们有屏幕 reader 用户和视力不佳的用户,他们都使用键盘进行导航,对于后者,我们希望帮助确定他们在哪个部分(在具有多个 section/cards) 而不会对屏幕 reader 用户产生负面影响。
当该部分突出显示时,我希望它只是图形化的(带有轮廓)但我不希望屏幕 reader 读取其内容,因为如果有 interactive/focusable里面的contente,会被读两遍,不要重复。
例如:使用像 ChromeVox 或 VoiceOver 这样的屏幕 reader,当按下 选项卡 时,第一部分将被勾勒出来,听起来像这样:
[Section] Section 1. 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.
再次点击 选项卡,第二部分将被勾勒出来,听起来像这样:
[Section] Section 2. 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. For example: this paragraph has tabindex. It should be read when focused.
第三次点击 选项卡 将激活该部分中的最后一段(它有一个 tabindex
),并且屏幕 reader 会显示:
For example: this paragraph has tabindex. It should be read when focused.
这种情况并不理想,因为我们在重复内容(记住上面的代码只是一个例子,实际上不止于此)。当一个部分获得焦点时,它会被完整地阅读;当里面的内容获得焦点时,它会被再次阅读。最后一句话被读了两遍:当该部分处于活动状态时以及它本身处于活动状态时。
我希望获得以下行为:
- 按 tab,第一部分高亮显示。未读取任何内容。
- 按tab,第二部分高亮显示。未读取任何内容。
- 按 tab,最后一段突出显示并阅读。
我尝试通过不同的方法来实现该行为:
- 使用
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>
我尝试用 aria-hidden="false"
将部分的全部内容包装成 div
,但似乎 parent 的 aria-hidden="true"
取代了它。
有没有办法实现我想要的?
简短回答:停止在任何地方添加 tabindex。屏幕 reader 用户使用阅读键进行导航,所以无论你想做什么都可以使事情变得可聚焦是没有意义的...
屏幕 reader 用户不需要 tabindex
使用键盘在文本中导航。
只有交互元素(按钮、链接、表单元素...)可以有 tabindex
。如果您使用本机交互元素(a[href]
button
、input
、...),则不必添加 tabindex
,仅适用于自定义控件 (<div role="button" tabindex="0">click here</div>
).
可聚焦元素不应位于另一个可聚焦元素内。
屏幕reader主要有two navigation mode:browse/reading模式(通常使用箭头键)和focus/form模式(使用tab
键).屏幕 reader 用户永远不会使用 tab
键来阅读非交互式文本。
您也不需要为当前阅读的文本添加大纲,因为屏幕reader 会在浏览模式下自动执行此操作。
我有一些代码看起来或多或少像这样(例如减少):
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 组件,我无法控制其中的内容。
我们有屏幕 reader 用户和视力不佳的用户,他们都使用键盘进行导航,对于后者,我们希望帮助确定他们在哪个部分(在具有多个 section/cards) 而不会对屏幕 reader 用户产生负面影响。
当该部分突出显示时,我希望它只是图形化的(带有轮廓)但我不希望屏幕 reader 读取其内容,因为如果有 interactive/focusable里面的contente,会被读两遍,不要重复。
例如:使用像 ChromeVox 或 VoiceOver 这样的屏幕 reader,当按下 选项卡 时,第一部分将被勾勒出来,听起来像这样:
[Section] Section 1. 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.
再次点击 选项卡,第二部分将被勾勒出来,听起来像这样:
[Section] Section 2. 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. For example: this paragraph has tabindex. It should be read when focused.
第三次点击 选项卡 将激活该部分中的最后一段(它有一个 tabindex
),并且屏幕 reader 会显示:
For example: this paragraph has tabindex. It should be read when focused.
这种情况并不理想,因为我们在重复内容(记住上面的代码只是一个例子,实际上不止于此)。当一个部分获得焦点时,它会被完整地阅读;当里面的内容获得焦点时,它会被再次阅读。最后一句话被读了两遍:当该部分处于活动状态时以及它本身处于活动状态时。
我希望获得以下行为:
- 按 tab,第一部分高亮显示。未读取任何内容。
- 按tab,第二部分高亮显示。未读取任何内容。
- 按 tab,最后一段突出显示并阅读。
我尝试通过不同的方法来实现该行为:
- 使用
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>
我尝试用 aria-hidden="false"
将部分的全部内容包装成 div
,但似乎 parent 的 aria-hidden="true"
取代了它。
有没有办法实现我想要的?
简短回答:停止在任何地方添加 tabindex。屏幕 reader 用户使用阅读键进行导航,所以无论你想做什么都可以使事情变得可聚焦是没有意义的...
屏幕 reader 用户不需要 tabindex
使用键盘在文本中导航。
只有交互元素(按钮、链接、表单元素...)可以有 tabindex
。如果您使用本机交互元素(a[href]
button
、input
、...),则不必添加 tabindex
,仅适用于自定义控件 (<div role="button" tabindex="0">click here</div>
).
可聚焦元素不应位于另一个可聚焦元素内。
屏幕reader主要有two navigation mode:browse/reading模式(通常使用箭头键)和focus/form模式(使用tab
键).屏幕 reader 用户永远不会使用 tab
键来阅读非交互式文本。
您也不需要为当前阅读的文本添加大纲,因为屏幕reader 会在浏览模式下自动执行此操作。