--- title: Scrollbar 滚动容器 description: 隐藏原生滚动条,用自绘滑块承载可滚动内容 --- # Scrollbar 滚动容器 `Scrollbar` 给内容区套一层自绘滚动条。它统一了各浏览器(尤其是 Windows 与 macOS)的滚动条外观,并保证在深色主题下也可见。 ## 何时使用 - 侧栏、面板、下拉列表等「内部滚动区域」需要与整体视觉统一时; - 原生滚动条太粗、或在深色主题下对比度不足时; - 高度固定的区域(必须给容器一个确定的高度,否则内容不会滚动)。 ## 基础用法 容器必须有确定高度(`height` / `max-height`),滚动才会生效。 ## 自动隐藏策略 `autoHide` 控制滚动条何时出现: | 取值 | 行为 | 适合 | | --- | --- | --- | | `never` | 常显(默认) | 长列表、始终需要滚动提示 | | `scroll` | 滚动时显示,停止后渐隐 | 阅读区、日志 | | `move` | 鼠标移入或滚动时显示 | 面板、卡片 | | `leave` | 鼠标移出后隐藏 | 需要极简视觉的展示区 | ## 无障碍 滚动区域是一个可聚焦容器(键盘 `↑ ↓ PageUp PageDown` 可滚动),因此需要给出可读名称: ```vue … ``` `visibility="hidden"` 时滚动条彻底不显示,但内容仍可滚动(键盘 / 触控板可用)。 ## API ### Props | 名称 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `visibility` | `'visible' \| 'auto' \| 'hidden'` | `'auto'` | 滚动条显示策略。`auto` 时按 `autoHide` 规则显隐;`hidden` 彻底不显示滚动条(仍可滚动) | | `autoHide` | `'never' \| 'scroll' \| 'move' \| 'leave'` | `'never'` | 自动隐藏策略,仅 `visibility="auto"` 时生效 | | `ariaLabel` | `string` | — | 滚动区域的无障碍名称,等价于 `aria-label` | ### Slots | 名称 | 参数 | 说明 | | --- | --- | --- | | `default` | — | 可滚动内容 | ### 类型定义 ```ts export type ScrollbarVisibility = 'visible' | 'auto' | 'hidden' export type ScrollbarAutoHide = 'never' | 'scroll' | 'move' | 'leave' export interface ScrollbarProps { visibility?: ScrollbarVisibility autoHide?: ScrollbarAutoHide ariaLabel?: string } ``` ### 样式变量 | 变量 | 默认值 | 说明 | | --- | --- | --- | | `--g3-scrollbar-size` | `8px` | 滚动条粗细 | | `--g3-scrollbar-thumb` | 半透明中性色 | 滑块颜色(hover 时加深) | | `--g3-scrollbar-track` | `transparent` | 轨道颜色 | ## 实现说明 - 滑块位置由 `scrollTop / scrollHeight` 实时换算,拖动滑块时反向写回滚动容器的 `scrollTop`;拖动期间给容器加 `is-dragging` 类,避免原生滚动干扰; - 尺寸变化(内容增删、容器缩放)通过 `ResizeObserver` 监听,滑块长度与可见性会自动更新,不需要手动 `update()`; - 隐藏原生滚动条用 `scrollbar-width: none` + `::-webkit-scrollbar { display: none }`,**不改** `overflow` 语义,因此键盘、触控板、`scrollIntoView` 全部照旧可用; - 不引第三方滚动库(如 overlayscrollbars),保持组件库零运行时依赖;代价是不支持原生「橡皮筋回弹」等平台特性。