如何优雅的满足 UI 对滚动条的苛刻要求

avatar
前端工程师

前言

在前端开发中,我们经常会遇到需要对滚动条样式进行定制的需求。这些需求包括但不限于:

  1. 定制滚动条的宽度和高度
  2. 定制滚动条的颜色
  3. 定制滚动条的形状
  4. 等等

在开始正文之前,先统一下滚动条各部分的名称。

image.png

W3C 标准

scrollbar-width

将滚动条的宽度定义为数值宽度或者预定义宽度,具体请查看 scrollbar-width

浏览器兼容性

image.png

scrollbar-color

定义滚动条的颜色,具体请查看 scrollbar-color

浏览器兼容性

image.png

scrollbar-gutter

用于控制经典滚动条模式下,滚动条所占据的空间或沟槽的位置,具体请查看scrollbar-gutter

这里介绍下经典滚动条和覆盖滚动条

  1. Classic Scrollbars:经典滚动条是指传统的滚动条样式,通常出现在页面的右侧或者底部,并且会占用页面的一定空间。用户可以通过鼠标滚轮、拖拽滚动条或者点击箭头来滚动页面。
  2. Overlay Scrollbars:覆盖滚动条是一种全新的滚动条显示方式,它会完全覆盖在页面内容上,用户可以通过鼠标滚轮或者拖拽来滚动页面,并且通常是部分透明的。

以下是主流浏览器对于经典滚动条和覆盖滚动条的支持情况:

  • Chrome:Chrome支持经典滚动条和覆盖滚动条,并默认使用覆盖滚动条。
  • Firefox:Firefox支持经典滚动条和覆盖滚动条,并默认使用覆盖滚动条。
  • Safari:Safari支持经典滚动条和覆盖滚动条,并默认使用覆盖滚动条。
  • Edge:Edge支持经典滚动条和覆盖滚动条,并默认使用覆盖滚动条。

具体区别可查看下图

image.png

浏览器兼容情况

image.png

下面列举下常用场景

image.png

滚动条现状

目前的主流浏览器(Chrome、Firefox、Edge、Safari)对滚动条的实现存在一定的差异。

Chrome

可以通过伪类去控制滚动条的样式,具体请看:

// 滚动条
::-webkit-scrollbar
// 轨道
::-webkit-scrollbar-thumb
// 滑块
::-webkit-scrollbar-track
// 滚动条上的按钮
::-webkit-scrollbar-button
// 滚动条没有滑块的轨道部分
::-webkit-scrollbar-track-piece
// 当同时有垂直滚动条和水平滚动条时交汇的部分
::-webkit-scrollbar-corner

基本可满足以下需求

  • 隐藏滚动条
  • 定制化滚动条样式

示例如下:

// 隐藏滚动条
.hideScroll::-webkit-scrollbar {
  display: none;
}

// 隐藏滚动条
.customizeScroll::-webkit-scrollbar {
  width: 6px;
  background-color: #eee;
}

.customizeScroll::-webkit-scrollbar-thumb {
  background-color: #c1c1c1;
  
  &:hover {
   background-color: #a8a8a8;
  }

  &:active {
   background-color: #787878;
  }
}

Firefox

Firefox 对滚动条的标准支持还是比较好的 可以通过scrollbar-widthscrollbar-color来定制滚动条样式

基本可满足以下需求

  • 隐藏滚动条
  • 部分定制化滚动条样式

示例

// 隐藏滚动条
.hideScroll {
 scrollbar-width: none;
} 

// 定制化滚动条样式
.customizeScroll {
 scrollbar-width: thin;
 scrollbar-color: #c1c1c1 #eee;
} 

Edge

与 Chrome 一致

Safari

与 Chrome 一致

解决方案

Css 修改

这是最简单的实现方式,具体实现请查看上面的描述。

实现滚动条部分,滚动行为使用浏览器原生的实现

本方案的思路是将滚动条隐藏,可通过多个 Div 的嵌套偏移(偏移量恰好是滚动条的宽度)或 Css 隐藏滚动条来实现。然后通过实现滚动条的样式和交互即可实现滚动条的定制化需求

社区已有实现

优点:

  1. 可以完全自定义滚动条样式
  2. 由于滚动行为使用的浏览器原生能力,性能有保障

缺点:

  1. 使用多层 Div 会破坏开发者预想的文档结构

实现滚动行为与滚动条

本方案比较复杂,需要考虑滚动行为的不同触发条件,同时需要考虑兼容问题以及各种边界问题。

社区已有实现

参考资源