Skip to content

VitePress 全站置顶组件

组件简介

这个置顶组件用于在页面向下滚动一段距离后,于右下角显示一个清新风格的悬浮按钮。它适合放在博客、文档站和内容型页面中,帮助用户更快回到顶部,减少长页面阅读后的操作成本。

当前项目中,这个组件以全站公共能力的方式接入,不需要在单篇文章里单独引入。只要页面使用了当前 VitePress 主题布局,首页、文章页和普通文档页都会自动拥有这个交互。

核心功能

  • 页面滚动超过 280px 后自动显示按钮,避免初始状态打扰阅读
  • 点击按钮后回到页面顶部,默认使用平滑滚动提升体验
  • 支持 prefers-reduced-motion,在减少动画模式下降级为即时回顶
  • 通过全局布局统一挂载,对首页和内容页同时生效
  • 提供可复用的主题级 CSS 变量,便于后续调整尺寸、位置和配色

使用方式

这个组件的源码位于 .vitepress/theme/components/BackToTopButton.vue,并通过以下两个入口接入:

  • .vitepress/theme/index.ts
  • .vitepress/theme/Layout.vue

接入方式延续了当前项目已有的主题扩展结构:

  1. 在主题入口引入置顶按钮对应的全局样式变量文件
  2. 在自定义 Layout 中引入组件
  3. 通过 layout-bottom 插槽挂载到全局布局底部

这样做的好处是不会侵入具体页面内容,也不需要在 Markdown 页面中重复引用。

实现思路

这个组件的实现逻辑比较直接,重点在于保证“全站通用”和“状态自然”:

  • 组件挂载后监听浏览器滚动事件
  • window.scrollY 超过 280px 时显示按钮,否则隐藏
  • 使用 requestAnimationFrame 合并高频滚动更新,避免滚动时频繁改写状态
  • 监听当前路由路径变化,在站内切页完成后重新同步显示状态
  • 检测系统是否开启“减少动画”,决定回顶时使用平滑滚动还是即时跳转

其中,路由切换后的状态同步很重要。因为用户可能从一篇很长的文章跳到一个较短页面,如果不重新判断,按钮有机会短暂残留在页面上。当前实现会在页面更新后再次检查滚动位置,保证显示状态正确。

样式与可配置项

当前组件对外暴露了以下主题级 CSS 变量,定义在 .vitepress/theme/styles/back-to-top.css

  • --blog-back-to-top-size
  • --blog-back-to-top-offset
  • --blog-back-to-top-bg
  • --blog-back-to-top-color
  • --blog-back-to-top-shadow

默认视觉方向是偏浅青和浅蓝的清新风格,配合轻阴影、圆形轮廓和半透明背景,让按钮在页面中更轻盈,不会显得太突兀。

按钮默认固定在右下角,并带有以下交互反馈:

  • 出现和隐藏时使用淡入与轻微上浮动效
  • 鼠标悬停时轻微抬升,强调可点击性
  • 键盘聚焦时显示清晰的可访问性描边
  • 移动端自动缩小尺寸并收紧边距,减少对阅读区域的遮挡

适用场景

这个组件比较适合以下场景:

  • 文章内容较长的个人博客
  • 章节型文档站
  • 需要频繁上下浏览的知识库页面
  • 希望增强阅读体验,但不想引入额外 UI 依赖的轻量项目

如果页面本身高度很短,或者希望交互尽量极简,这类组件的价值就会相对有限。

后续优化方向

如果后面还想继续完善,可以考虑这些方向:

  • 增加按页面类型控制显隐的能力
  • 为首页和内容页提供略有区别的视觉风格
  • 补一张组件效果截图,方便在组件栏目中展示
  • 抽离滚动状态逻辑,给其他悬浮类组件复用