回到顶部
概述
SBacktop 在滚动目标超过可配置阈值后显示浮动按钮,激活时平滑滚动目标回到顶部。它封装了 SButton,提供滚动位置追踪、基于 requestAnimationFrame 的平滑滚动和 prefers-reduced-motion 支持。用于让用户在长页面或可滚动容器中快速返回顶部。
注意:除了
SBacktop,Aria 层还导出了Backtop,可用于自定义组合。
用法
功能
- 📏 可见性阈值 — 滚动超过
visibilityHeight像素后按钮才出现(默认400)。 - 🎬 平滑动画 — 使用
easeInOutCubic缓动在duration毫秒内滚动到顶部(默认300)。设duration={0}可即时滚动。 - ♿ 减弱动画 — 尊重
prefers-reduced-motion: reduce;用户偏好减弱动画时跳过动画即时滚动。 - 🎯 灵活目标 —
target接受window(默认)、HTMLElement、Ref<HTMLElement>或 CSS 选择器字符串。 - 🔧 Aria 组合 — Aria
Backtop单独导出用于自定义按钮样式;SBacktop提供预设buttonVariants+ 固定定位。 - 🎨 完整 Button props — 继承所有
ButtonProps(color、size、variant、shape、shadow、disabled 等)及icon/iconClass/iconProps默认图标。 - 📡 事件 — 发射
change(可见性切换)和click(按钮点击)。 - 🌐 SSR 安全 — 所有浏览器 API(
window、document、matchMedia)均有守护;服务端渲染无错误。
演示
基础
Scroll inside the container to reveal the Backtop button.
目标容器
Backtop can observe a selector target and render custom content.
自定义样式
Use button style props, slot content, and custom positioning classes.
API
Aria 层
1Backtop
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
class | ClassValue | — | 应用于根元素的额外类名。 |
color | ThemeColor | — | 组件的主题颜色。 |
size | ThemeSize | — | 组件的视觉尺寸。 |
variant | ButtonVariant | — | 该组件的视觉变体。 |
shape | ButtonShape | — | 组件的结构。 |
shadow | ButtonShadow | — | 遵循该组件的样式规范。 |
fitContent | boolean | — | 组件是否应适应其内容宽度。 |
icon | string | 'lucide:arrow-up' | iconify 的图标名称。 |
iconClass | ClassValue | — | 图标的类。 |
iconProps | Partial<IconProps> | — | 图标的 props。 |
visibilityHeight | number | 400 | 必须滚动到该距离后,“返回顶部”按钮才会显示。 |
target | AffixTarget | null | window | Backtop 监听并滚动的滚动目标。 |
duration | number | 300 | 滚动至顶部动画的持续时间(单位:毫秒)。 |
disabled | boolean | — | 该组件是否已禁用。 |
asChild | boolean | — | 将默认渲染元素替换为作为子元素传递的元素,并合并两者的属性及行为。 |
as | AsTag | Component | 'div' | 该组件应渲染为的元素或组件。可通过 `asChild` 进行覆盖。 |
type | ButtonType | 'button' | 按钮元素的类型。可以是 'button'、'submit' 或 'reset' 之一。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
change | boolean | 在发生变更时触发。 |
click | PointerEvent | 在发生点击时触发。 |
注意事项
架构与对标差异
SBacktop 拆分为 Aria 层(负责滚动追踪、目标解析、动画和可见性状态)和 styled 层(负责 backtopVariants 配方,扩展 buttonVariants 加 fixed z-50 和基于尺寸的 bottom-* end-* 定位)。遵循 VeanUI Aria/styled 分离模式。
| 维度 | VeanUI | Ant Design BackTop | Element Plus Backtop | Naive UI BackTop |
|---|---|---|---|---|
| 架构 | Aria + styled 分离 | 仅 styled | 仅 styled | 仅 styled |
| 平滑滚动 | requestAnimationFrame + easeInOutCubic | requestAnimationFrame | requestAnimationFrame | requestAnimationFrame |
| 减弱动画 | ✅ prefers-reduced-motion | — | — | — |
| 目标类型 | window / HTMLElement / Ref / CSS 选择器 | HTMLElement / 函数 | HTMLElement / 字符串 | HTMLElement / 字符串 |
| 可见性阈值 | visibilityHeight(number) | visibilityHeight(number) | visibilityHeight(number) | visibilityHeight(number) |
| 动画时长 | duration(ms) | — | — | — |
| Aria 导出 | ✅ Backtop | — | — | — |
| 禁用状态 | ✅ 继承自 Button | — | — | — |
运行时注意事项
hidden属性:按钮不可见时,Aria 层在<button>上设置hidden,应用display: none。这会阻止显示/隐藏的 CSS 过渡。如需淡入淡出过渡,覆盖[hidden] { display: block; }并在自定义类中使用 opacity/visibility 过渡。- 焦点管理:按钮在聚焦状态下变为不可见时(如滚动到顶部后),Aria 层自动失焦,防止焦点被困在隐藏元素上。
- 滚动监听清理:Aria 层使用
useEventListener配合onWatcherCleanup,在目标变更或组件卸载时移除滚动监听器。无需手动清理。 target响应性:运行时修改target或visibilityHeight会触发目标重新解析和通过nextTick的可见性重检。
常见问题
如何指定特定的可滚动容器作为目标? 传入元素或 CSS 选择器:<SBacktop target="#my-scroll-container" /> 或 <SBacktop :target="scrollRef" />。组件会解析目标并监听其 scroll 事件。
如何禁用平滑动画? 设 duration={0}:<SBacktop :duration="0" />。用户启用 prefers-reduced-motion: reduce 时组件也会自动跳过动画。
可以使用自定义按钮替代默认样式吗? 可以。从 @vean/aria/backtop 导入 Aria Backtop,用自定义按钮组合:
<script setup lang="ts">
import { Backtop } from '@vean/aria/backtop';
</script>
<template>
<Backtop :visibility-height="200" class="my-custom-button">
<MyIcon />
</Backtop>
</template>为什么点击后按钮立即消失? 滚动到顶部后,滚动位置低于 visibilityHeight,按钮因此隐藏。Aria 层在隐藏前自动失焦按钮,避免焦点被困在隐藏元素上。
如何更换默认图标? 传入 icon prop:<SBacktop icon="lucide:chevron-up" />。使用 iconClass 控制图标样式,iconProps 传递额外 SIcon props。