锚点链接:稳定的页面内导航规则
使用锚点链接创建稳定的页面内导航,保存标题ID,保护被引用的片段URL,帮助读者无摩擦地找到答案。
锚点链接是页面内链接,将读者带到当前文档的指定章节。它们将长页面转化为一组持久、可寻址的答案——但前提是每个目标都有一个稳定的标题 ID。
跳转到: 为什么锚点链接很重要 · 何时使用 · 稳定ID的结构 · 实现语法 · QA检查清单
上面这行是该元素以紧凑的内联形式呈现的效果。每个链接包含一个片段标识符,即 # 之后的部分,每个片段对应本页上的一个标题。
为什么这个元素很重要
长文档在产生阅读问题之前,首先会产生检索问题。从搜索结果、支持工单或同事消息中到达的访问者往往只需要一个具体要点,而不是整篇论证。一个描述性的跳转链接免去了滚动,并向访问者保证答案的存在。它还支持非线性阅读:读者可以查看参数、返回结构分析,然后进入 QA,而无需假装每次有用的访问都从引言开始。
心理上的好处依赖于信任。链接文本对目标做出承诺,点击必须立即兑现。像"了解更多"这样模糊的标签迫使读者记住周围的上下文。一个落在粘性页眉下方的链接即使浏览器在技术上到达了正确的坐标,也会让人感觉有问题。一个包含近 25 个几乎相同条目的列表又创造了一个扫描任务,而不是减少一个。
锚点链接还提高了机器可提取性——即软件隔离一个章节并在完整页面之外保留其含义的能力。像 /guide/#renewal-terms 这样的 URL 标识了一个比 /guide/ 更小的答案区域。搜索引擎、浏览器扩展、文档工具和 AI 检索系统可以直接引用或分享该区域。片段不会创造权威性或保证被引用,但它给已经有用的章节提供了一个精确的公开地址。
这个地址是一个接口,而不是标题的附带产物。许多发布系统会从可见标题"Renewal terms"生成 renewal-terms。如果编辑后来将标题改为"How renewals work",生成器可能会产生 how-renewals-work。每个仍然以 #renewal-terms 结尾的入站链接现在指向一个不再存在的 ID。这包括其他文章中的链接、浏览器书签、活动消息、帮助中心回复、搜索结果和被引用的 AI 答案。页面 URL 仍然成功返回,这可能掩盖了退步,但访问者失去了承诺的章节级目标。
在添加导航之前,请遵循元素写作规则 。优先级规则仍然适用:锚点链接导航到内容元素;它们不取代必需的定义、比较、警告、常见问题或其他类型化块。标题系统 拥有文档层级结构和附加在标题上的稳定 ID。锚点链接使用这些 ID。
何时使用
当页面包含读者可能独立需要的多个目标时,使用锚点链接。典型场景包括:带有离散参数的冗长参考文档、包含设置和故障排除部分的文档、包含方法论和发现分开的报告、包含命名义务的政策页面,以及包含问题分组的常见问题中心。
当以下条件中至少一项为真时,使用可见的跳转链接集:
- 页面有五个或更多有意义的 H2 章节,且读者可能带着不同的目标进入。
- 页面长度为 1800 字或更长,且各章节可以非线性方式理解。
- 支持、销售、法律或编辑团队经常分享指向个别章节的链接。
- 某个章节可能被独立引用、收藏、重新访问或更新。
- 移动端读者否则需要大量滚动才能到达可预测的答案。
即使没有可见的跳转链接列表,每个实质性的标题仍然可以拥有一个 ID。稳定的目标保存起来成本低廉,但在链接传播之后重建则代价高昂。
接近但不完全符合条件的情况需要克制。一个三步线性流程通常应让读者按顺序进行;跳转列表可能让人跳过前置条件。一个短页面,其标题已经显示在首屏之上,不会获得有用的导航。标签页和折叠面板控制的是界面状态切换,而不是导航到文档位置,因此它们不能替代锚点链接。分页链接在文档之间移动。指向另一个页面的链接是内部链接,即使其目标恰好包含一个片段。
不要将锚点作为关键词策略使用,也不要制造额外的标题以获得更多的片段 URL。导航单元必须是一个真实的章节,具有明确的目的和足够的内容来满足链接标签的承诺。
放置位置
将页面级的跳转链接组放置在英雄区、直接答案或简要范围说明之后,第一个主要正文章节之前。读者需要先理解页面,然后选择浏览路径。当页面也使用了快速概览和目录 时,不要添加第二个相同目标的列表。目录是锚点链接的一种呈现形式;应配置或简化该元素,而不是重复导航。
将局部跳转链接组紧放在它所控制的限定区域之前,例如字母顺序目录或多部分 API 参考。给它一个命名范围的标签:“跳转到产品系列"比另一个通用的"本页内容"更清晰。在句子中放置内联交叉引用,指向目标变得有用的位置,使用能命名目标的词语。
不要将锚点导航放置在:
- 标题和回答该标题的段落之间。
- 主张与其证据、限定条件或来源之间。
- 与不相关的 CTA、广告、新闻通讯表单或促销卡片旁,这些会争夺同一次点击。
- 另一个链接、按钮、标题或交互式控件内部。
- 在导航后覆盖目标标题的粘性区域中。
- 在它旨在帮助读者发现的内容之后。
如果粘性站点页眉高 72 像素,目标需要至少该滚动偏移量加上舒适的间距。在目标处通过一致的 scroll-margin-top 解决这个问题,而不是插入空的间隔元素或用 JavaScript 更改片段。
结构
锚点链接系统包含七个部分:
- 导航标签: 命名集合,通常为"本页内容"或特定范围的替代名称。
- 链接文本: 脱离周围句子阅读时描述目标的内容。
- 片段 href: 以
#开头用于当前页面,如#renewal-terms。 - 目标 ID: 目标上的唯一值,完全匹配不带
#的 href。 - 目标标题: 告知到达的读者他们已到达何处以及接下来是什么。
- 到达偏移: 保持标题在粘性界面栏下方可见。
- 交互状态: 使悬停、键盘焦点、适当时的已访问状态以及当前位置可感知。
可见标题和 ID 是相关但不相同的。标题可能为了清晰而更改。一旦公开,只要章节保留相同的目的,ID 就保持固定。ID 使用小写 ASCII 字母、有意义的数字和连字符:#cancel-subscription 是可移植的;#Section 4! 则不是。
设计示例
每个变体都使用相同的链接到 ID 的约定。变体之间的区别在于上下文和密度,而不是发明新的目标行为。
紧凑内联: 在开头附近使用三到六个同级目标。允许换行,并保持分隔符不在无障碍链接名称中。
堆叠列表: 当标签需要空间或扫描比垂直空间更重要时,使用五到十二个目标。这是长指南和政策的默认样式。
嵌套列表: 使用 H2 目标作为主要路径,仅包含实质性的 H3 子章节。深度限制在两个导航层级;更深的层级属于文档导航。
局部索引: 使用字母、类别或参考组来导航一个限定区域。将不存在的目标呈现为纯禁用样式的文本,而不是带有空或虚假目标的链接。
标题永久链接: 当读者经常引用个别章节时,在标题旁边提供一个小的复制链接控件。其无障碍名称必须包含标题,例如"复制链接到 Renewal terms”。标题本身保持为文本,而不是一个大自链接。
内联交叉引用: 当一段文字依赖于另一个章节时,使用正常的句子链接。优先使用"查看续约条款"而不是"跳转到此处"。
参数
集合和每个目标都有独立的字段。在可移植指令体中,第一个标题根据默认主体规则映射到导航标签;后续列表项提供链接。
| 名称 | 类型 | 必填 | 最小/最大 | 默认值 | 来源 |
|---|---|---|---|---|---|
label | 纯文本字符串 | 集合必填 | 2–6 个词;最多 60 个字符 | On this page | 属性或主体中的第一个标题 |
variant | 枚举 | 否 | inline, stacked, nested, local-index, permalink | stacked | 属性 |
items | 链接集合 | 集合必填 | 3–12 个可见项;A-Z 索引允许 26 个 | 无 | 主体列表 |
text | 纯内联文本 | 每项必填 | 2–10 个词;最多 70 个字符 | 目标标题文本 | 主体链接标签 |
href | 片段 URL | 每项必填 | 一个 #id;无空片段 | 从 targetId 派生 | 主体链接目标或项属性 |
targetId | 唯一的 HTML ID | 必填 | 1–8 个小写连字符标记 | 首次发布前从标题文本生成,然后固定 | 目标标题属性或编辑器锚点字段 |
depth | 整数枚举 | 否 | 1 或 2 | 1 | 属性;可从主体嵌套派生 |
copyable | 布尔值 | 否 | true 或 false | false | 属性 |
content | Markdown 链接列表 | 集合变体必填 | 一个与 items 匹配的列表;无纯文本主体 | 第一个主体标题之后的所有内容 | 主体 |
编辑项目标故意小于技术上限。如果某个页面需要 18 个目标,首先对相关章节进行分组,使用生成的目录,或者拆分文档。A-Z 索引是一个狭隘的例外,因为它的顺序和标签已经是可预测的。
语法和代码示例
可移植源显式存储链接文本和片段,以便在不丢失已发布 ID 的情况下在不同渲染器之间迁移。
可移植 Markdown 指令
:::anchor-links{variant=stacked depth=1}
### On this page
- [Eligibility](#eligibility)
- [Required documents](#required-documents)
- [Renewal terms](#renewal-terms)
:::
## Eligibility {#eligibility}
第一个主体标题成为 label;列表成为 content 并提供 items。在页面首次发布时固定目标 ID。
Hugo 短代码
{{< anchor-links variant="stacked" label="On this page" >}}
- [Eligibility](#eligibility)
- [Required documents](#required-documents)
- [Renewal terms](#renewal-terms)
{{< /anchor-links >}}
## Eligibility {#eligibility}
这是 Hugo 适配器约定,并非声称此仓库已注册 anchor-links 短代码。Hugo 实现可以从 .TableOfContents 生成列表,或渲染普通的 Markdown 链接,前提是保留相同的 ID、语义、限制和无障碍行为。
WordPress
<!-- wp:group {"tagName":"nav","ariaLabel":"On this page"} -->
<nav aria-label="On this page">
<ul>
<li><a href="#eligibility">Eligibility</a></li>
<li><a href="#required-documents">Required documents</a></li>
<li><a href="#renewal-terms">Renewal terms</a></li>
</ul>
</nav>
<!-- /wp:group -->
<!-- wp:heading {"level":2,"anchor":"eligibility"} -->
<h2 id="eligibility">Eligibility</h2>
<!-- /wp:heading -->
对于已发布的目标,明确设置 WordPress 的高级 → HTML 锚点字段。不要依赖主题或插件从更改后的可见文本重新生成 ID。
示例
好示例:标签和 ID 在编辑改进后仍然存活
**On this page**
- [Calculate the total cost](#calculate-total-cost)
- [Compare contract terms](#compare-contract-terms)
- [Choose a plan](#choose-plan)
## Compare annual and monthly contract terms {#compare-contract-terms}
这样做有效,因为导航标签预测了不同的答案,ID 可读且唯一,标题可以变得更具体而不改变已发布的 #compare-contract-terms 地址。在措辞改进之前创建的引用仍然能够到达正确的章节。
坏示例:生成的 ID 被视为可丢弃的
- [More information](#more-information)
- [Click here](#section-4)
- [Pricing](#pricing-2026)
## New pricing details
这里失败是因为两个标签需要周围上下文,section-4 编码的是位置而非含义,而 pricing-2026 在年份变更时会变得误导。标题也已更改,但没有保留旧的 id="pricing-2026",因此现有的入站片段不再解析。重命名列表条目无法修复已在其他地方发布的链接。
结构化数据标记与无障碍
锚点链接不提供专用的 Schema.org 类型。不要仅仅因为跳转链接列表使用 <ul> 就将其标记为 ItemList;其目的是导航,而非排名或策划的实体集合。目标章节可能会为 Article、FAQPage、HowTo 或其他适当的页面级 Schema 类型贡献可见内容,但片段本身不是独立的结构化数据。
使用原生的 <a href="#target-id"> 链接。当页面级或局部组是一个独立的导航区域时,用 <nav aria-label="On this page"> 包裹它。不要给原生锚点添加 role="link"。每个目标 ID 必须是唯一的,href 必须完全匹配,包括大小写。
键盘用户需要可见的焦点指示器。触摸目标需要足够的间距以避免意外激活。链接文本必须能识别目标,而不依赖颜色、附近的文字或 title 属性。如果复制永久链接控件使用按钮,请在不意外移动焦点的情况下宣布成功。
片段导航必须使目标标题在粘性页眉下方保持可见。优先在目标上使用 CSS scroll-margin-top。平滑滚动是可选的,且必须尊重减少运动偏好。避免取消原生链接行为、从浏览器历史记录中移除片段、或更改滚动位置而不更新 URL 的 JavaScript。
不要为每个普通片段点击自动移动焦点;原生的浏览器行为应保持可预测。如果自定义菜单或披露面板在激活后关闭且焦点可能丢失,则有意将焦点移动到可以接收焦点的目标,例如带有 tabindex="-1" 的标题,然后使用键盘和屏幕阅读器导航进行测试。当状态准确更新时,持续导航控件可以使用 aria-current="location" 指示当前目标。
写作规则
在页面大纲稳定之后、链接传播之前编写目标。使用句子大小写和具体名词或动词。标签应在脱离上下文时仍然有意义,因为复制的链接、屏幕阅读器链接列表和机器引用可能将其从原始视觉上下文中移除。
- 在可见组中使用三到十二个链接;紧凑开头集优先使用五到八个。
- 保持标签在两到十个词之间,不超过 70 个字符。
- 默认包含 H2 目标。仅在 H3 满足独立需求时才包含它。
- 在组内保持一种语法模式:全部为问题、全部为名词短语或全部为祈使动词。
- 使用一到八个由小写字母和连字符分隔的标记。以字母开头,省略标点、表情符号、变音符号、会过期的日期和位置数字。
- 冻结每个公开 ID。当章节目的保持不变时,可见标题可以更改而不改变其 ID。
- 永远不要将已退役的 ID 用于无关内容。旧的链接不能看起来有效却指向不同的主张。
- 永远不要在导航标签中放入引用、脚注标记、价格、促销徽章或紧急性声明。
- 永远不要将按钮、表单控件、图像或其他链接放入锚点链接内部。
- 永远不要使用"点击这里"、“阅读更多”、“详情"或"章节"作为完整的标签。
当某个章节被移除时,决定旧片段承诺了什么。如果其内容移到了同一页面上的等效章节,则在平台支持多个锚点的情况下,将旧 ID 保留为新目标旁边的别名。如果不存在等效内容,不要默默地将旧 ID 附加到不同的章节。记录移除并更新每个已知的内部引用。
使用该元素的内容类型
postTypes 前置元数据数组驱动此关系。包含意味着该格式通常受益于稳定的章节目标;并不要求每个短实例都有可见的跳转列表。
QA 检查清单
- 页面有真实的非线性导航需求;列表不是装饰。
- 每个可见链接标签在单独阅读时描述其目标。
- 每个 href 以
#开头用于同页面链接,并精确匹配一个现有目标 ID。 - 每个目标 ID 是唯一的、小写的、可读的,且不包含临时日期或位置数字。
- 已发布的 ID 已与前一版本比较,除非有记录的迁移,否则保持不变。
- 可见标题重命名在其章节目的不变时保留旧 ID。
- 已移除或合并的目标不会将旧 ID 用于不同内容。
- 组包含 3–12 个有用的项目,除非是有正当理由的 A-Z 局部索引。
- H3 目标仅在它们内容充实且正确嵌套在 H2 下时出现。
- 该组不与目录或相邻导航组件重复。
- 导航不打断标题与其答案、主张与其证据、或必需顺序。
- 该组使用原生链接,并且当独立时,使用命名的导航地标。
- 键盘焦点可见且遵循逻辑顺序。
- 目标标题在桌面和移动宽度的粘性页眉下方保持可见。
- 存在平滑滚动时尊重减少运动偏好。
- 复制链接控件命名目标并在不丢失焦点的情况下宣布成功。
- 直接加载每个完整 URL 加片段在全新页面加载后到达预期的章节。
- 已知的入站内部链接、支持材料中使用的书签和被引用的片段 URL 在编辑后已进行回归测试。
当页面本身加载但已知片段不再解析时,拒绝发布。断开的锚点是章节级别的断开的入站链接,即使页面级别监控报告了成功响应。
常见问题
上面的问题涵盖了发布后最常破坏锚点导航的维护决策。它们的权威答案位于结构化的 [[faq]] 前置元数据中,以便可见的 FAQ 输出和任何符合条件的结构化数据输出可以使用相同的来源。
准备好付诸实践了吗?
免费检查 · 7天试用 · 无需信用卡