如何让 Mac 上的 VoiceOver 读取 aria-label
(或其他 aria-
属性)而不与 tabindex
冲突?
我正在尝试为具有如下结构的搜索结果页面提供一些可访问性内容
<div class="header">
<input value="" name="search" type="search"/>
</div>
<div class="main">
<div class="adv-block">
<a href="#">Link to adv 1</a>
<a href="#">Link to adv 2</a>
</div>
<div class="search-result">
<a href="#">Search result 1</a>
<a href="#">Search result 2</a>
</div>
</div>
首先,我希望用户能够通过选项卡导航跳过广告,因此我为输入和搜索结果提供 tabindex,如下所示。
<div class="header">
<input value="" name="search" tabindex="1" type="search"/>
</div>
<div class="main">
<div class="adv-block">
<a href="#">Link to adv 1</a>
<a href="#">Link to adv 2</a>
</div>
<div class="search-result">
<a href="#" tabindex="2">Search result 1</a>
<a href="#" tabindex="3">Search result 2</a>
</div>
</div>
但是我想帮助屏幕阅读程序(在我的例子中是 Mac 上的 VoiceOver)来正确读取区域。因此,我用其角色和描述标记了搜索结果容器。
<div class="header">
<input value="" name="search" tabindex="1" type="search"/>
</div>
<div class="main" role="main" aria-label="Search results">
<div class="adv-block">
<a href="#">Link to adv 1</a>
<a href="#">Link to adv 2</a>
</div>
<div class="search-result">
<a href="#" tabindex="2">Search result 1</a>
<a href="#" tabindex="3">Search result 2</a>
</div>
</div>
问题是 VoiceOver 还根据 tabindex
进行导航,并从输入直接转到第一个链接。
我试图通过向容器添加 tablindex
属性来作弊
<div class="header">
<input value="" name="search" tabindex="1" type="search"/>
</div>
<div class="main" role="main" aria-label="Search results" tabindex="2">
<div class="adv-block">
<a href="#">Link to adv 1</a>
<a href="#">Link to adv 2</a>
</div>
<div class="search-result">
<a href="#" tabindex="3">Search result 1</a>
<a href="#" tabindex="4">Search result 2</a>
</div>
</div>
但是这种情况会改变通常的选项卡导航。
那么,有没有办法让 VoiceOver 读出用户已进入搜索结果区域?
最佳答案
在尝试强制使用特定的导航样式时请务必小心,因为选项卡并不是使用屏幕阅读器进行导航的唯一(甚至主要)方法。
大多数时候,屏幕阅读器用户会使用“浏览”导航来阅读内容。在 VoiceOver 中,这是 cntl-alt-右箭头,在 Jaws/NVDA 中,它只是向下箭头。
浏览模式将浏览所有内容,而不仅仅是表单控件和链接。浏览模式不受tabindex的影响。
tabindex 的问题在于它会覆盖默认(代码)顺序,当它与浏览顺序不匹配时,这可能会非常困惑。当页面中有其他内容,然后您跳过内容 block 并转到最低的 tabindex 时,这种情况会更加明显。
我会推荐类似的东西:
<header role="banner">
<div class="header" role="search">
<label for="search" class="hidden">Search</label>
<input value="" name="search" type="search" id="search">
</div>
</header>
<div class="adv-block">
<a href="#">Link to adv 1</a>
<a href="#">Link to adv 2</a>
</div>
<main role="main" id="main" aria-labelledby="results">
<h1 id="results" class="hidden">Search results</h1>
<div class="search-result">
<a href="#" tabindex="2">Search result 1</a>
<a href="#" tabindex="3">Search result 2</a>
</div>
</main>
注意:我假设 header 中还会有其他内容,否则不值得使用具有横幅角色的 header 。
使用屏幕阅读器的人获取“内容”的典型方式是:
- 向下箭头浏览所有内容,耗时但可靠。
- 按标题跳过(VoiceOver 中的 cntl-alt-cmd-h),主标题 1 可以很好地指示页面的主要内容。
- 打开地标对话框(cntl-alt-u,然后向左/向右在 VO 中找到它)并转到“主”地标。
- 通过链接进行 Tab 键切换,一致性胜过效率。
总的来说,我建议不要尝试操纵制表符顺序,并确保提供良好的标题、地标,如果您确实需要提供快捷方式,也许还可以提供跳过链接。这也适用于基于 Windows 的屏幕阅读器。
关于accessibility - VoiceOver (Mac) 使用 tabindex 进行导航并忽略 aria- 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19588544/