虽然大多数在电脑上浏览网页的人使用鼠标,但许多人依赖键盘。理论上,使用键盘操作网页不应该有问题——按 TAB 键将键盘焦点从一个 可聚焦元素 移动到下一个,然后按 ENTER 键激活,很简单!然而,许多(如果不是大多数)网站都倾向于在页面顶部有一个链接菜单,有时需要按很多次才能到达你想要的内容。以 20min 的主页 为例,这是瑞士最大的新闻网站之一。你想阅读头条新闻?这将需要大约 40 次按键——这对任何人的时间来说都不是最佳利用方式。
因此,如果你希望键盘用户真正使用你的网站,而不是感到厌烦并转到其他地方,你需要在幕后做一些工作,使直接跳到主要内容更快更容易。你可以在网上找到各种各样的技巧(包括 CSS-Tricks 上的这篇),但大多数都忽略了一些技巧,许多推荐使用过时或已弃用的代码。因此,在本文中,我将深入探讨跳至内容,并以 2021 年友好的方式涵盖所有内容。
两种类型的键盘用户
尽管人们用来导航的确切键盘或等效 切换设备 类型存在许多差异,但从编码的角度来看,我们只需要考虑两组人
- 将键盘与屏幕阅读器一起使用的人——例如 PC 上的 NVDA 或 JAWS,或 Mac 上的 VoiceOver——这些设备会大声朗读屏幕上的内容。这些设备通常由视力障碍更严重的人使用。
- 所有其他键盘用户。
我们的跳至内容技巧需要同时满足这两组用户的需求,同时又不妨碍所有鼠标用户。我们将使用两种互补的技术来获得最佳结果:**地标**和**跳过链接**。
查看一个基本示例
我创建了一个名为 Style Magic 的示例网站来说明我们正在介绍的技术。我们将从对鼠标用户来说工作正常但对使用键盘的用户来说有点麻烦的状态开始。你可以在 CodePen 上的这个集合 中找到基本站点以及每种技术的版本,并且,因为在 CodePen 上测试键盘导航有点 棘手,你也可以在这里找到 独立版本。
尝试使用 TAB 键来导航此示例。(在 独立页面 上更容易;TAB 从一个链接移动到下一个,SHIFT+TAB 向后移动。)你会发现它并不太糟糕,但这仅仅是因为菜单项不多。
如果你有时间并且在 Windows 上,那么我还建议你下载 NVDA 屏幕阅读器 的免费副本,并使用它尝试所有示例,参考 WebAIM 的使用概述。大多数 Mac 用户已经可以使用 VoiceOver 屏幕阅读器,并且 WebAIM 也提供了使用它的优秀入门指南。
添加地标
屏幕阅读软件可以做的一件事是显示他们在网页上找到的**地标**列表。地标 代表页面上的重要区域,用户可以调出该列表,然后直接跳转到其中一个地标。
如果你使用的是带有完整键盘的 NVDA,你可以按 INS+F7 调出“元素列表”,然后按 ALT+d 显示地标。(你可以通过使用 网页项目转子 在 VoiceOver 上找到类似的列表。)但是,如果你在示例网站上执行此操作,则只会显示一个无用的空列表。

让我们先解决这个问题。
**添加地标非常容易**,如果你使用的是 HTML5,你可能已经在你的网站上使用了它们而没有意识到,因为它们直接与 HTML5 语义元素(<header>
、<main>
、<footer>
等)相关联。
以下是用于生成网站标题部分的 HTML 的前后对比
<div class="bg-dark">
<div class="content-width flex-container">
<div class="branding"><a href="#">Style Magic</a></div>
<div class="menu-right with-branding">
<a href="#">Home</a>
<!-- etc. -->
</div>
</div>
</div>
变成
<div class="bg-dark">
<header class="content-width flex-container">
<section class="branding"><a href="#">Style Magic</a></section>
<nav aria-label="Main menu" class="menu-right with-branding">
<a href="#">Home</a>
<!-- etc. -->
</nav>
</header>
</div>
使用的类保持不变,因此我们不需要对 CSS 进行任何更改。
以下是我们需要在示例网站中进行的所有更改的完整列表
- 表示页面顶部标题的
<div>
现在是<header>
元素。 - 包含品牌信息的
<div>
现在是<section>
元素。 - 包含菜单的两个
<div>
已替换为<nav>
元素。 - 两个新的
<nav>
元素已获得aria-label
属性,用于描述它们:页面顶部的菜单为“主菜单”,页面底部的菜单为“实用程序菜单”。 - 包含页面主要内容的
<div>
现在是<main>
元素。 - 表示页面底部页脚的
<div>
现在是<footer>
元素。
你可以在 CodePen 上查看完整的更新后的 HTML。
让我们再次尝试 NVDA 中的地标列表技巧(INS+F7,然后 ALT+d——这是 独立页面的链接,以便你可以自行测试)

太棒了!我们现在有了 banner
地标(映射到 <header>
元素)、Main menu; navigation
(映射到顶部 <nav>
元素,并显示我们的 aria-label
)、main
(映射到 <main>
)和 content info
(映射到 footer
)。在此对话框中,我可以使用 TAB
和光标键选择 main
地标并直接跳到页面内容,或者更好的是,我可以在浏览页面时按下 D
键,从一个地标角色直接跳转到下一个。JAWS 屏幕阅读器的用户使用起来更简单——他们在浏览时只需按下 Q
键即可直接跳转到 main
地标。
作为一个额外的好处,使用语义元素还有助于搜索引擎更好地理解和索引你的内容。这是使网站更易访问的一个不错的额外好处。
添加跳过链接
我想你此刻正悠闲地想着“工作完成”。好吧,我担心总要考虑一个“但是”。谷歌在 2011 年进行了一些研究,研究在网页中使用 CTRL+f 进行搜索,发现惊人的 90% 的人要么不知道它存在,要么从未使用过它。使用屏幕阅读器的用户在使用地标时行为方式大致相同——很大一部分人根本不使用此功能,即使它非常有用。因此,我们将向我们的网站添加一个**跳过链接**,以帮助这两组用户以及所有不使用屏幕阅读器的键盘用户。
构成良好跳过链接的基本要求是
- 它**应该**在需要时对所有键盘用户(包括屏幕阅读器用户)可见。
- 它**应该**向键盘用户提供足够的信息来解释它的作用。
- 它**应该**在尽可能广泛的当前浏览器上都能正常工作。
- 它**不应该**干扰鼠标用户的浏览。
步骤 1:改进键盘焦点外观
首先,我们将改进网站上键盘焦点的可见性。您可以将键盘焦点视为在文字处理器中编辑文本时光标位置的等效项。当您使用TAB键进行导航时,键盘焦点会从一个链接移动到另一个链接(或表单控件)。
最新的网络浏览器在显示键盘焦点位置方面做得不错,但仍然可以从辅助功能中受益。有很多创意的方式来设置焦点环的样式,尽管我们的目标是使其尽可能地脱颖而出。
我们可以使用:focus
伪类来设置样式(并且最好将相同的样式也应用于:hover
,我们已经在示例网站上做了——CodePen,线上站点)。这是我们至少可以做的,尽管通常会更进一步,并在整个页面上的:focus
中反转链接颜色。
这是我们:focus
状态的一些 CSS(我们已经为:hover
准备好的副本)
a:focus { /* generic rule for entire page */
border-bottom-color: #1295e6;
}
.menu-right a:focus,
.branding a:focus {
/* inverted colors for links in the header and footer */
background-color: white;
color: #1295e6;
}
步骤 2:添加 HTML 和 CSS
最后一个更改是将跳过链接本身添加到 HTML 和 CSS 中。它由两部分组成,**触发器**(链接)和**目标**(路标)。这是我推荐用于触发器的 HTML,放置在页面开始处,<header>
元素内部
<header class="content-width flex-container">
<a href="#skip-link-target" class="text-assistive display-at-top-on-focus">Skip to main content.</a>
<!-- etc. -->
</header>
这是目标的 HTML,放置在<main>
内容开始之前
<a href="#skip-link-target" class="text-assistive display-at-top-on-focus" id="skip-link-target">Start of main content.</a>
<main class="content-width">
<!-- etc. -->
</main>
HTML 的工作原理如下
- 跳过链接触发器使用标准页面片段(
href="#skip-link-target"
)链接到跳过链接目标,该片段引用目标的id
属性(id="skip-link-target"
)。点击链接会将键盘焦点从触发器移动到目标。 - 我们链接到一个锚(
<a>
)元素,而不是直接在<main>
元素上添加id
属性,原因有两个。首先,它避免了键盘焦点无法正确移动的任何问题(这在某些浏览器中可能是一个问题);其次,这意味着我们可以向用户提供清晰的反馈,以表明跳过链接已成功。 - 这两个链接的文本具有描述性,以便清楚地向用户解释正在发生的事情。
我们现在有一个可用的跳过链接,但是有一个问题:它对所有人可见。我们将使用 CSS 默认隐藏它,这样可以避免它妨碍鼠标用户,然后仅当它接收到键盘焦点时才显示它。有很多方法可以做到这一点,并且大多数方法都可以,但有一些错误的方法应该避免。
- 建议:使用
clip-path
使链接不可见,或使用transform: translate
或position: absolute
将其放置在屏幕外。 - 不建议:使用
display: none
、visibility: hidden
、hidden
属性,或将跳过链接的width
或height
设置为零。所有这些都会使您的跳过链接对于一类或两类键盘用户无法使用。 - 不建议:使用
clip
,因为它已弃用。
这是我推荐隐藏这两个链接的代码。使用clip-path
及其前缀-webkit-
版本在撰写本文时,它适用于 96.84% 的用户,这(在我看来)对于大多数网站和用例来说都是可以的。如果您的用例需要,还有许多其他技术可用,这些技术在WebAIM 上有详细介绍。
.text-assistive {
-webkit-clip-path: polygon(0 0, 0 0, 0 0, 0 0);
clip-path: polygon(0 0, 0 0, 0 0, 0 0);
box-sizing: border-box;
position: absolute;
margin: 0;
padding: 0;
}
并且为了在链接获得焦点时显示它们,我建议使用此 CSS 版本,颜色和大小与您的品牌相匹配
.text-assistive.display-at-top-on-focus {
top: 0;
left: 0;
width: 100%;
}
.text-assistive.display-at-top-on-focus:focus {
-webkit-clip-path: none;
clip-path: none;
z-index: 999;
height: 80px;
line-height: 80px;
background: white;
font-size: 1.2rem;
text-decoration: none;
color: #1295e6;
text-align: center;
}
#skip-link-target:focus {
background: #084367;
color: white;
}
这提供了触发器和目标在页面顶部非常明显的显示,用户期望在页面加载后直接看到键盘焦点。点击链接后还会发生颜色变化,以提供清晰的反馈,表明某些操作已发生。您可以在CodePen 上(如下所示)自己修改代码并使用 NVDA 在独立页面上进行测试。
更进一步
跳过链接不仅仅用于圣诞节您的主菜单,无论何时您的网页包含很长的链接列表,它们都非常有用。实际上,此 CodePen演示了在页面内容中使用跳过链接的良好方法(此处为独立页面),在 CSS 中使用transform: translateY()
来隐藏和显示触发器和目标。如果您“幸运地”需要支持旧版浏览器,那么您可以在此 CodePen 上找到一种针对此方法(此处为独立页面)。
让我们看看!
最后,这里有一些简短的视频演示了跳过链接如何对我们两类键盘用户起作用。
以下是使用 NVDA 屏幕阅读器时完成的跳过链接的工作方式
当使用键盘(无屏幕阅读器)浏览时,它再次显示如下
我们刚刚介绍了我在 2021 年认为是现代可访问跳过链接方法的内容。我们借鉴了过去示例中的一些想法,同时对其进行了更新,以适应更好的 CSS 实践、改进的键盘用户界面以及改进的屏幕阅读器用户体验,这得益于对 HTML 的更新方法。
不确定这是否仍然相关,但在 HTML5 Boilerplate 存储库中有一个问题提到了 clip-path:“视觉隐藏中的 clip-path 会破坏滚动性能。”
https://github.com/h5bp/html5-boilerplate/issues/2021
有人知道这是否仍然相关吗?
我花了一些时间才找到相关的错误报告(此处:https://bugs.chromium.org/p/chromium/issues/detail?id=611257)——看起来这个问题已在 2020 年 8 月发布的 Chrome 85 中修复
很棒的文章,谢谢。如果您有多个跳过链接组合在一起(例如跳至主导航、跳至主要内容、跳至搜索、跳至站点索引),是否应该将它们组合在一个
<nav aria-label="Skip links">
元素中?谢谢,很高兴你喜欢它!如果您有一堆跳过链接组合在一起,那么我会像任何其他导航菜单一样标记它们,因此
<nav aria-label="Skip links">
在我看来是合适的。不过,拥有大量这样的跳过链接的情况很少见,因此我只会在我觉得页面非常复杂或例如 Web 应用程序时才这样做。在 Vivaldi 中根本无法使用。与任何其他网站不同,Vivaldi 浏览器无法通过 Tab 访问页面的任何内容。在 Firefox 中运行良好
默认情况下,Vivaldi 使用与其他浏览器不同的键盘导航方法,称为“空间导航”,此处有描述:https://help.vivaldi.com/desktop/shortcuts/spatial-navigation/——基本上,您使用
Shift
加光标键在页面上的链接等周围进行视觉移动,对于看得清楚的键盘用户来说,这种方法使跳过链接变得不必要。Opera 在切换到使用 Blink 之前也使用了相同的系统。您可以通过关闭空间导航并将“网页焦点”设置为“聚焦所有控件和链接”来将 Vivaldi 切换到传统的TAB
键盘导航方法。谢谢!读起来很棒,而且信息量很大。
感谢这篇文章。我之前一直在使用跳至内容链接,但很高兴能看到 2021 年的更新!干得好
感谢你撰写这篇内容。如果你打算跳到一个实际的链接而不是以编程方式聚焦区域(我倾向于这样做),我建议进行一些小的调整。首先,我建议将其放在 `` 内部;这样,当链接获得焦点时,屏幕阅读器就会宣布主要地标。这样做,“主要内容开始”的措辞就变得不必要了(如果链接在 `` 外部,它实际上也不是真的)。但是,删除链接文本会导致 NVDA 将链接宣布为“主要地标,可点击”。在链接上放置 `aria-hidden="true"` 仍然会使它获得焦点,但不会为链接本身宣布任何内容,并且你仍然会收到主要地标的公告。
感谢你的反馈!对我来说,在目标链接上删除链接文本的问题在于,我们会失去对那些不使用屏幕阅读器的仅键盘用户的重要反馈。我对于将目标链接放在 `` 元素内有些犹豫。从语义上讲,它可能更有意义,但如果屏幕阅读器用户使用地标角色跳到内容,那么他们会先听到链接读出,而不是内容本身,此外,我不确定它是否也可能产生(轻微的)负面 SEO 影响,因此我选择将其放在 `` 之前而不是放在 `` 内。
嗨,Paul,感谢你的回复(尽管我没有你评论的回复链接,所以最终看起来可能像我在回复我自己)。我对关于失去面向键盘用户的视觉反馈的评论感到好奇;页面通常会滚动到焦点所在的位置,因此对于视觉反馈来说应该足够了。你说的链接会在内容之前被读出是正确的(尽管主要地标应该在链接文本之前被宣布),这就是为什么我倾向于使用 `aria-hide` 的原因。我不确定 SEO 影响,我倾向于认为它即使存在也是微不足道的(当然需要测试才能知道),但鉴于我的工作重点,我通常更担心可访问性 :) 最后,当然,在可访问性实施方面有很多争论,但即使实施方式略有不同,拥有一个跳过链接也比没有好得多。
抱歉说了这么多评论,但我最终写了一篇博客文章,表达了我对此的看法:https://plousia.com/blog/some-thoughts-css-tricks-deep-dive-skipping-content(希望允许链接)。请记住,这些旨在使可访问性实施变得更好,而不是过于苛刻——最重要的是有一个有效的跳过链接,这使得你比没有的网站领先很多。
随时欢迎反馈!我只是想澄清一下我对非屏幕阅读器键盘用户的反馈的观点。你说“当使用页面片段进行导航时,页面通常会滚动到焦点所在的位置”,但这并不是真的:首先,页面需要足够长才能进行滚动,否则根本不会发生任何事情。当有 `fixed` 或 `sticky` 位置元素时,滚动位置也可能变得非常混乱。因此,此方法避免了这些问题,并确保始终对键盘焦点所在的位置提供积极的视觉反馈。关于 SEO 的问题,搜索引擎使用 `` 元素来帮助他们识别页面的最重要部分,此部分顶部的内容权重最高。因此,将链接放在 `` 之外有助于使页面的内容对他们更加清晰。
谢谢,很棒的文章!这对我很及时,因为越来越多的客户要求提供可访问性功能。