上个月,Heather Migliorisi 查看了平滑滚动的无障碍性。 为了实现平滑滚动,您需要
- 检查点击的链接是否是 #jump 链接
- 停止浏览器将页面立即跳转到该元素的默认行为
- 将滚动动画到 #jump 链接指向的元素
停止浏览器的默认行为是影响无障碍性的部分。 #jump 链接不再将焦点移动到 #jump 链接指向的元素。 因此 Heather 添加了 #4:将焦点移动到 #jump 链接指向的元素。
但是,并非所有元素都可以在 JavaScript 中移动焦点。 有时您需要强制该元素可聚焦,她通过设置 tabindex="-1"
来实现。
我们随后更新了 我们的代码片段 以进行更易于访问的焦点处理。 从那时起,我们收到了很多人的反馈,他们遇到了更新后的代码片段的一个新副作用

平滑滚动后,滚动到的标题现在具有链接默认具有的蓝色发光轮廓。 即使我们并不总是喜欢蓝色发光轮廓(样式因用户代理而异,例如,它可能是点状轮廓),我们也知道最好将其删除。
甚至还有一个专门针对此观点的网站

如果愿意,您可以更改焦点样式,但对于处于焦点的元素具有不同的焦点样式,这对于无障碍性来说是件好事。 我甚至可以想象一个保留焦点样式的论点。
但是但是但是
标题不是可聚焦元素。
它们不是“交互式”元素。 我们不习惯在非交互式元素上看到焦点样式。 但是现在,突然之间,因为我们使用了互联网上的平滑滚动技术,所以我们得到了它们。 允许焦点的 tabindex="-1"
技术导致了这种情况。
我联系了 Heather 询问此事。
标题和其他非交互式元素的
:focus
样式可以删除/不显示。 这实际上取决于创意网站背后的用户是否希望将其保留在那里。 在某些情况下,我将其删除了,在其他情况下我对其进行了样式设置。 这取决于具体情况。
令我惊讶的是,如果强制聚焦的元素不是交互式的,则可以删除焦点样式。 最后一点很重要,Heather 澄清了这一点
只要标题不是链接……;)
因此,如果您真的讨厌焦点样式,您可以执行以下操作
h1:focus,
h2:focus,
h3:focus,
h4:focus,
h5:focus,
h6:focus {
outline: 0;
}
您在那里是安全的。 即使在 <a><h3></h3></a>
或 <h3><a></a></h3>
的情况下,链接仍然具有焦点样式。
不仅仅是标题
跳转链接可以指向任何元素,并且有很多默认情况下不可聚焦的元素。 在这种情况下,另一种经典的技术是“黄色渐变”技术。 假设我们不是链接到标题,而是链接到 <section>
。 当任何部分都处于焦点时,我们可以这样对其进行样式设置
section:focus {
outline: 0;
animation: yellowFade 3s forwards;
}
@keyframes yellowFade {
from { background: lightYellow; }
to { background: white; }
}
这给了我们

这是对 通常用于 :target 的内容的改编。
我通常使用如下内容来删除非交互式元素上的焦点(我唯一赋予负 tabindex 的元素)
// 防止在仅应通过 Javascript 设置焦点的元素上出现焦点轮廓。
// 通过 Javascript。
*[tabindex="-1"] {
outline: none;
}
为什么不使用默认的
:target
选择器并将焦点保留给交互式元素?我怀疑从非交互式元素中删除焦点环是否可以。 焦点环的作用不仅仅是指示某些内容是否具有交互性。 它可以帮助键盘用户跟踪焦点顺序。 当元素获得焦点但没有任何视觉指示时,这对这些用户来说会令人困惑。 想象一下,您是键盘用户,正在一个页面上按 Tab 键,并且您在一行中连续有三个或四个这样的可聚焦标题。 您按了 3 次以上 Tab 键,但没有任何反应。 在这一点上,您可能会合理地认为您陷入了某个焦点的陷阱,放弃,刷新等。这并不是一个好的体验。
这不是问题,因为
[tabindex="-1"]
元素不参与 Tab 键顺序。 该属性所做的只是使元素可以通过 JavaScript 获得焦点。我看到 Jon 比我先说出来了,但是是的,为了键盘的可访问性,我们应该保留元素焦点,以便用户始终知道他们在哪里。 它也是 WCAG 要求的一部分(据我所知)。 现在,我在所有可访问的网站上所做的是添加 Javascript 来指示交互来自哪里
el.addEventListener('mousedown', () => {
el.setAttribute('data-focus-method', 'mouse');
});
el.addEventListener('blur', () => {
el.removeAttribute('data-focus-method');
});
这样,当用户通过鼠标进行交互时,我就可以删除所有(或大部分)轮廓。 在给定的示例中,可能需要在更高的 DOM 上设置属性。
感谢您提供此更新! 它非常及时,阻止了我破坏无障碍性。