按下选项卡时,NVDA 在初始页面加载时跳过第一个可聚焦元素

Zip*_*ppy 6 html accessibility focus nvda

最近,在尝试使我的网站可访问时,我偶然发现了一个奇怪的问题。在设置“跳过导航”链接的过程中,我注意到当页面最初加载时(“初始加载”,我的意思是在干净的浏览器会话中,而不是刷新\xe2\x80\x94,因为 NVDA 会跟踪最后一个焦点元素的位置,因此结果将取决于该元素)。

\n

当页面加载并按下 Tab 键时,接收焦点的元素是第二个元素(正如您从下面的简化示例中看到的那样,它是站点徽标/名称(也是锚链接))。

\n

当 NVDA 未运行时,问题不会出现...一切都按预期运行,无论 NVDA 运行或不运行,Firefox 都可以正常工作,但 Chrome、Edge 和 Opera 桌面中存在问题。到目前为止我还没有在任何其他浏览器上测试过它。

\n

请注意,由于问题的性质,我没有包含可运行的代码片段或小提琴(因为屏幕上会有其他元素,并且正如我所说,这个问题仅在新的浏览器会话/干净页面加载时显示) .这是一些简化的代码来显示问题......

\n

CSS

\n
body, html {\n  margin: 0;\n}\n\n.skip-nav {\n  position: absolute;\n  margin: 10px 0 0 10px;\n  white-space: nowrap;\n  display: inline-block;\n  padding: 0;\n}\n\n.skip-nav a {\n  position: absolute;\n  left: -1000px;\n  border: 2px solid blue;\n  border-radius: 2px;\n  background-color: black;\n  padding: 5px;\n}\n\n\n/* Move link into viewport when focused */\n.skip-nav a:focus {\n  left: initial;\n}\n\nnav {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  height: 30px;\n  background-color: darkblue;\n  padding: 10px;\n  color: white;\n}\n\nnav ul {\n  list-style: none;\n}\n\nnav li {\n  display: inline;\n  margin: 0 5px 0 5px;\n}\n\na {\n  text-decoration: none;\n  color: white;\n}\n\na:hover {\n  color: rgb(165, 165, 165);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

超文本标记语言

\n
<!-- Should get focus first, only does in FF when NVDA is running, not in other tested browsers -->\n<div class="skip-nav">\n  <a href="#main-content">Skip navigation</a>\n</div>\n\n<!-- Dummy nav bar -->\n<nav>\n  <a href="#">Name</a>\n  <ul>\n    <li><a href="#">Home</a></li>\n    <li><a href="#">Services</a></li>\n    <li><a href="#">About</a></li>\n    <li><a href="#">Contact</a></li>\n  </ul>\n</nav>\n  \n<!-- Main site content -->\n<section id="main-content">\n  Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi dolores voluptates temporibus culpa in quia et magni laborum architecto fugit!\n</section>\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试过的事情

\n

我做的第一件事就是在 Chrome 隐身模式下禁用所有浏览器扩展/测试。然后我在上面提到的其他浏览器中尝试了。我还尝试了其他可聚焦元素(例如按钮,甚至设置了“tabindex=0”属性的 div。我还将初始链接放在自己的位置上(不在父 div 内)。所有结果都相同。

\n

解决方法

\n

我没有将链接放在 div 中,而是将其放在 ul/li 中...并且它工作得很好...

\n
<!-- Using a UL works... but not with bullets hidden\n<ul class="skip-nav">\n  <li>\n    <a href="#main-content">Skip navigation</a>\n  </li>\n</ul>\n
Run Code Online (Sandbox Code Playgroud)\n

所以我想我应该在 CSS 中使用以下属性设置列表......

\n
list-style: none;\n
Run Code Online (Sandbox Code Playgroud)\n

子弹消失了,但问题又回来了……

\n

现在,我坚持使用“修复”,但我没有将列表样式设置为无,而是简单地从列表中删除了填充,这样当它位于屏幕左侧时,项目符号仍然保持关闭状态- 屏幕和隐藏。我已经在所有浏览器中对此进行了测试,并且它可以工作,除了屏幕阅读器在遍历元素时仍然会读取并宣布“项目符号”(在 NVDA 中,使用箭头键)这一事实之外。这不是一个巨大的破坏因素,但这似乎是实现(接近)期望结果的一种非常“hacky”的方式。

\n

总而言之,要重现该问题,浏览器必须是一个新会话。页面加载后,第一次按 Tab 键应将链接聚焦在“skip-nav”div 中。目前,在上面的示例中,初始选项卡似乎忽略了第一个链接(除非在项目符号列表中)。然而,向后移动选项卡确实按照预期集中链接。

\n

我有什么遗漏的吗?

\n

Gra*_*hie 8

这是一个视觉焦点问题,当您加载页面时,焦点被放置在文档上(通过浏览器),并且如果第一个链接没有包装在<ul>. NVDA 也没有报告该项目使用NVDA+进行聚焦Tab

然而,如果您按下Space激活该链接,您将看到它确实随着 URL 更新而聚焦。

我的猜测是,这与焦点以编程方式更改时 NVDA 如何放置审阅光标以及它如何与页面上的第一个项目交互有关。

此外,如果您在页面加载后将焦点放入 URL 栏(重置焦点)并Tab放入文档中,它将按预期运行。

这似乎是一个长期存在的错误,但我找不到任何关于该过程的哪个特定部分导致此问题的答案。这也是我直到今天才意识到的一个错误,因此我将进行更多挖掘(我的网站受到此影响)。

我唯一能想到的是,浏览器聚焦文档,页面上的第一个链接是第一个文本,当审阅光标放在它上面时,它假设该链接已激活(或者在文档被打开之前由 NVDA 设置焦点)渲染...不过纯粹是猜测)。

如何为自己修复

解决此问题的一种方法是更改​​ NVDA 中的设置。

Right click NVDA icon -> Preferences -> Review cursor... -> uncheck "Follow system focus".

此时,您将看到页面上的第一项自动正确聚焦。

查看光标窗口,显示未选择的第一个选项(跟随系统焦点)

如何为其他人修复

它是否需要修复是有争议的,Tab屏幕阅读器用户不像其他方法那样经常使用它,而且事实上它只在一个全新的会话中(我的意思是我从来没有注意到它,我经常使用屏幕阅读器,尽管只是用于测试而不是作为全职用户)我想大多数人不会受到影响。

因为只有当页面上的第一个文本是链接时才会出现这种情况,您也许可以通过在其前面添加一个带有空格的跨度来解决它(我没有机会测试)。

<div class="skip-nav">
  <span>&nbsp;</span>
  <a href="#main-content">Skip navigation</a>
</div>
Run Code Online (Sandbox Code Playgroud)

在对上述内容进行一些测试后,我将回到这个问题,但可能需要几天的时间才能有机会。

更新

我似乎是正确的,添加一个带有空格的跨度可以解决问题并且焦点可以正确显示。

在下面的小提琴中测试了完整的 HTML,刚刚添加<span>&nbsp;</span>到 中<header>,第一个链接然后按预期显示焦点:

<div class="skip-nav">
  <span>&nbsp;</span>
  <a href="#main-content">Skip navigation</a>
</div>
Run Code Online (Sandbox Code Playgroud)