跳过导航链接
跳过导航链接(Skip Links)是一种让键盘用户快速跳过重复的导航区域、直达页面主要内容的技术。它通常以"跳到主要内容"这样的链接形式出现,虽然视觉上默认隐藏,但当用户按 Tab 键时它会显示出来。Skip Links 是实现无障碍键盘导航最简单但最有效的方式之一。
前置知识
阅读本节前,建议先了解:键盘导航
为什么需要 Skip Links
许多网站在页面顶部有重复出现的导航栏、面包屑、搜索框等元素。键盘用户每次刷新页面或跳转到新页面时,都需要逐个 Tab 穿过这些重复元素才能到达主要内容区域。当导航项目很多时,这个过程非常繁琐。
Skip Links 解决的问题:
- 键盘用户可以按一次 Tab 就跳到"跳到主要内容"链接
- 点击后直接跳到页面主要内容区域
- 屏幕阅读器用户可以直接跳到主要内容
- 符合 WCAG 2.4.1(A 级)要求:提供绕过重复内容块的方法
基础实现
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Skip Links 基础示例</title>
<style>
/* 跳过链接默认视觉隐藏 */
.skip-link {
position: absolute;
top: -100%; /* 移出视口 */
left: 0;
padding: 0.5rem 1rem;
background: #0066cc;
color: white;
text-decoration: none;
font-weight: bold;
z-index: 1000;
border-radius: 0 0 4px 0;
}
/* 获得焦点时显示 */
.skip-link:focus {
top: 0; /* 回到视口顶部 */
outline: 3px solid #ff6600;
outline-offset: 2px;
}
</style>
</head>
<body>
<!-- 跳过导航链接:页面第一个可聚焦元素 -->
<a href="#main-content" class="skip-link">跳到主要内容</a>
<!-- 导航栏 -->
<header>
<nav aria-label="主导航">
<a href="/">首页</a>
<a href="/products">产品</a>
<a href="/about">关于</a>
<a href="/contact">联系我们</a>
</nav>
</header>
<!-- 主内容区域,需要有 id 匹配 skip-link 的 href -->
<main id="main-content">
<h1>页面标题</h1>
<p>这是页面的主要内容区域。</p>
</main>
</body>
</html>多个 Skip Links
页面可以提供多个跳过链接,让用户根据需要跳转到不同区域:
html
<body>
<!-- 多个跳过链接 -->
<a href="#main-content" class="skip-link">跳到主要内容</a>
<a href="#search" class="skip-link">跳到搜索</a>
<a href="#footer" class="skip-link">跳到页脚</a>
<header>
<nav aria-label="主导航">
<a href="/">首页</a>
<a href="/products">产品</a>
<a href="/about">关于</a>
</nav>
</header>
<main id="main-content">
<h1>文章标题</h1>
<p>主要内容...</p>
</main>
<aside>
<form id="search">
<label for="search-input">搜索</label>
<input type="search" id="search-input" />
</form>
</aside>
<footer id="footer">
<p>版权所有 2024</p>
</footer>
</body>视觉隐藏的 CSS 技术
技术对比
| 技术 | 说明 | 屏幕阅读器可访问 | 视觉可见 |
|---|---|---|---|
display: none | 完全移除 | 否 | 否 |
visibility: hidden | 占据空间但不可见 | 否 | 否 |
opacity: 0 | 透明但仍占据空间 | 是 | 否 |
position: absolute; clip | SR-only 经典方案 | 是 | 否 |
clip-path | 裁剪为 0 | 是 | 否 |
.sr-only 类 | 推荐:SR-only 专用 | 是 | 否 |
推荐的 sr-only 类
css
/* 屏幕阅读器专用样式:视觉隐藏,辅助技术可访问 */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0); /* 旧浏览器支持 */
clip-path: inset(50%); /* 现代浏览器 */
white-space: nowrap;
border: 0;
}
/* 获得焦点时恢复显示 */
.sr-only-focusable:focus,
.sr-only-focusable:focus-within {
position: static;
width: auto;
height: auto;
padding: auto;
margin: auto;
overflow: visible;
clip: auto;
clip-path: none;
white-space: normal;
}html
<!-- 使用 Tailwind CSS 的 sr-only 类 -->
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-50 focus:bg-white focus:p-2 focus:border focus:border-blue-500">
跳到主要内容
</a>Skip Links 的焦点样式
Skip Links 获得焦点时的视觉效果非常重要,因为它们通常只在按 Tab 键时才可见:
css
/* Skip Links 聚焦样式 */
.skip-link {
/* 默认隐藏 */
position: absolute;
top: -100%;
left: 16px;
padding: 12px 24px;
background: #1a1a2e;
color: #ffffff;
font-size: 1rem;
font-weight: 600;
text-decoration: none;
border-radius: 0 0 8px 8px;
z-index: 9999;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
transition: top 0.2s ease, box-shadow 0.2s ease;
}
/* 聚焦时显示 */
.skip-link:focus {
top: 0;
outline: 3px solid #4ecdc4;
outline-offset: 2px;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
}id 目标元素的处理
Skip Links 通过锚点跳转,目标元素需要正确处理焦点移动:
html
<!-- 方案 1:直接使用 main 元素的 id(部分浏览器会自动聚焦) -->
<main id="main-content">
<h1>页面标题</h1>
</main>
<!-- 方案 2:在目标位置添加 tabindex="-1" 确保聚焦 -->
<main id="main-content" tabindex="-1">
<h1>页面标题</h1>
</main>
<!-- 方案 3:JavaScript 增强 -->
<script>
document.querySelector('.skip-link').addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.setAttribute('tabindex', '-1');
target.focus({ preventScroll: false });
}
});
</script>tabindex="-1" 的影响
在 <main> 上添加 tabindex="-1" 不会改变 Tab 顺序,但允许通过 JavaScript 将焦点移到该元素。这是一个常见的无障碍最佳实践。
实战示例:完整的 Skip Links 实现
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>完整 Skip Links 示例</title>
<style>
/* 重置样式 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; line-height: 1.6; }
/* Skip Links 样式 */
.skip-links {
position: relative;
z-index: 9999;
}
.skip-link {
position: absolute;
left: 0;
top: -100%;
padding: 8px 16px;
background: #0066cc;
color: #fff;
font-weight: 600;
font-size: 0.875rem;
text-decoration: none;
border-radius: 0 0 4px 0;
transition: top 0.15s ease;
}
.skip-link:focus {
top: 0;
outline: 3px solid #ff6600;
outline-offset: 2px;
}
/* 导航栏 */
.site-header {
background: #1a1a2e;
color: #fff;
padding: 1rem 2rem;
}
.site-header nav {
display: flex;
gap: 1rem;
}
.site-header a {
color: #fff;
text-decoration: none;
padding: 0.25rem 0.5rem;
}
.site-header a:focus-visible {
outline: 2px solid #4ecdc4;
outline-offset: 2px;
}
/* 主内容 */
.site-main {
padding: 2rem;
max-width: 800px;
margin: 0 auto;
}
.site-main:focus {
outline: none;
}
</style>
</head>
<body>
<!-- Skip Links -->
<div class="skip-links">
<a href="#main-content" class="skip-link">跳到主要内容</a>
<a href="#site-nav" class="skip-link">跳到导航</a>
<a href="#site-footer" class="skip-link">跳到页脚</a>
</div>
<!-- 网站头部 -->
<header class="site-header">
<div class="logo">我的网站</div>
<nav id="site-nav" aria-label="主导航">
<a href="/">首页</a>
<a href="/products">产品</a>
<a href="/services">服务</a>
<a href="/blog">博客</a>
<a href="/about">关于我们</a>
<a href="/contact">联系我们</a>
</nav>
</header>
<!-- 主内容区域 -->
<main id="main-content" class="site-main" tabindex="-1">
<h1>欢迎访问我的网站</h1>
<p>这是网站的主要内容区域。通过使用 Skip Links,键盘用户可以快速跳过导航栏,直接到达此处。</p>
<section>
<h2>最新文章</h2>
<article>
<h3>HTML5 入门教程</h3>
<p>学习 HTML5 的基础知识,包括语义化标签、表单控件、多媒体等。</p>
<a href="/html5-intro">阅读更多</a>
</article>
</section>
</main>
<!-- 页脚 -->
<footer id="site-footer">
<nav aria-label="页脚导航">
<a href="/privacy">隐私政策</a>
<a href="/terms">服务条款</a>
</nav>
<p>版权所有 2024</p>
</footer>
<script>
// 增强 Skip Links 的跳转行为
document.querySelectorAll('.skip-link').forEach(link => {
link.addEventListener('click', function(e) {
const targetId = this.getAttribute('href').substring(1);
const target = document.getElementById(targetId);
if (target) {
// 确保 target 可以接收焦点
if (!target.hasAttribute('tabindex')) {
target.setAttribute('tabindex', '-1');
}
// 聚焦并滚动到目标
target.focus({
preventScroll: false
});
// 移除 tabindex(可选,避免 Tab 时停在 main 上)
// 注意:某些无障碍规范建议保留 tabindex="-1"
}
});
});
</script>
</body>
</html>注意事项
- Skip Links 必须是页面中第一个可聚焦元素:确保它在 DOM 中位于最前面
- 目标元素必须有对应的 id:href 中的锚点必须与目标元素的 id 匹配
- 不要使用 display:none:这会使屏幕阅读器也无法感知到链接
- 确保聚焦后视觉指示清晰:Skip Links 只在获得焦点时才可见
- 测试实际的键盘体验:使用 Tab 键验证 Skip Links 的行为是否符合预期
最佳实践
- 每个页面至少提供"跳到主要内容"的 Skip Link
- 为多区域页面提供多个 Skip Links(如搜索、导航、页脚)
- 使用
.sr-only+:focus技术实现视觉隐藏但键盘可见 - 在目标元素上使用
tabindex="-1"确保焦点可以正确转移 - 使用 JavaScript 增强跳转行为,确保跨浏览器一致性
- 风格要醒目,确保用户能看到获得焦点的 Skip Link
下一节
继续学习:屏幕阅读器兼容