登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  前端

CSS scroll-target-group 怎样让目录项跟随当前章节高亮

来源:17golang原创

时间:2026-10-24 22:53:18 128浏览 收藏

做长文档目录时,我以前常用 JavaScript 监听滚动位置,再给当前目录项加一个 active 类。这个方案当然能用,但要维护观察器、偏移量和清理逻辑。现在如果页面只需要“目录链接对应当前章节高亮”,可以先看看 scroll-target-group:它把已有的目录链接纳入滚动标记组,再用 :target-current 表达当前目标。

规范与兼容性参考:https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-target-group

先说结论:目录容器设置 scroll-target-group: auto,目录中的 与章节的 id 对齐,再给 :target-current 写高亮样式即可。这个能力目前仍是 Experimental、Limited availability,适合渐进增强,不能把它当成所有浏览器都具备的基础能力。

  • 目录链接必须使用 fragment,且能找到对应的章节 id。
  • auto 负责建立滚动标记组,:target-current 负责表达当前项。
  • 不支持时保留普通锚点导航,页面仍然能跳转,只是不显示自动跟随的高亮。

先把目录和章节接上

这一步不需要新 API。目录项的 href 指向章节 id,章节使用唯一的 id。下面的示例把目录和两个章节放进同一个页面结构中:

问题背景

这里放第一节内容。

布局关系

这里放第二节内容。

这里最容易出错的是拼写不一致:href="#intro" 必须对应 id="intro",不要把显示文字当成选择器,也不要让多个章节复用同一个 id。先把这个普通锚点关系搭好,后面的 CSS 才有明确目标。

让目录链接成为滚动标记组

把 scroll-target-group: auto 放在包住这些链接的目录列表上。然后用 :target-current 选中当前滚动目标对应的链接。为了让键盘焦点和鼠标悬停仍然有反馈,我会把它们和当前状态一起写:

/* 先保留普通链接的可读样式,未支持时也能使用 */
.scroll-nav a {
  color: #40506a;
  text-decoration: none;
}

/* 让目录列表成为滚动标记组容器 */
.scroll-nav {
  scroll-target-group: auto;
}

/* 当前章节对应的目录项获得醒目状态 */
.scroll-nav a:hover,
.scroll-nav a:focus-visible,
.scroll-nav a:target-current {
  color: #5b3cc4;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

关键关系有两个:目录容器负责把内部 fragment 链接识别为滚动标记,:target-current 再负责匹配当前可见章节的目录项。它解决的是“哪个目录项处在当前目标状态”,不是替你生成目录,也不是替你修复错误的 id。

目录容器、fragment 链接、章节 id 与 target-current 的静态结构关系说明图
图1:结构说明图,查看目录链接如何对应章节 id,以及 :target-current 在当前目标状态中的位置。

为什么它能跟着当前章节变化

浏览器会把带 fragment identifier 的目录链接与页面中的目标元素联系起来。当目标章节进入当前视野时,对应链接可以通过 :target-current 呈现状态;点击目录时,原有的 fragment 导航关系也仍然成立。这样,目录跳转和滚动阅读都共享同一组 HTML 关系,代码不需要额外保存“当前是第几节”的状态。

这也是它和常见“给每个链接绑定滚动监听”的思路不同的地方:文章只声明目录链接与章节的对应关系,状态由浏览器的滚动标记机制表达。对于章节目录、横向卡片导航这类已有锚点的场景,这个模型更轻;如果页面需要复杂的阅读进度、跨容器联动或业务埋点,仍然要单独设计更完整的交互状态。

用渐进增强处理支持边界

MDN 将这个属性标为 Limited availability 和 Experimental,生产页面不要直接假设所有用户都能看到自动高亮。可以用 @supports 把增强样式收起来,同时让默认链接样式始终存在:

/* 基础层:所有浏览器都保留可点击、可聚焦的目录链接 */
.scroll-nav a {
  color: #40506a;
  text-decoration: none;
}

/* 增强层:只有同时理解属性和值的浏览器才启用自动高亮 */
@supports (scroll-target-group: auto) {
  .scroll-nav {
    scroll-target-group: auto;
  }
}

/* 当前状态选择器不被识别时,基础链接仍然不受影响 */
@supports selector(.scroll-nav a:target-current) {
  .scroll-nav a:target-current {
    color: #5b3cc4;
    font-weight: 700;
  }
}

这段写法的保底结果很明确:支持新能力的浏览器获得自动高亮,不支持的浏览器依旧能点击目录跳转。不要为了追求统一视觉而删掉普通链接的颜色、焦点轮廓或可访问名称。

scroll-target-group 原生增强、supports 条件和普通锚点保底的静态依赖说明图
图2:边界说明图,查看实验性 CSS 能力与普通锚点保底之间的关系。

常见问题

为什么设置了属性却没有高亮?

先检查浏览器是否实现了该实验特性,再检查目录链接是否真的带有 fragment,以及 fragment 是否能匹配唯一章节 id。三者缺一不可。

需要为每次滚动额外写 JavaScript 吗?

只做本文的目录高亮不需要。先用原生能力渐进增强;当需求扩大到复杂阅读进度、跨容器同步或业务事件记录时,再引入脚本方案。

总结

scroll-target-group 的价值不在于替页面自动生成目录,而在于把已有的目录链接提升为滚动标记,再用 :target-current 表示当前章节。先保证 fragment 和 id 的结构正确,再用 @supports 做增强,页面就能在新能力和普通锚点之间保持清晰的兼容边界。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>