跳到主要內容
前端開發

::-webkit-scrollbar 捲軸樣式調整整理

整理 WebKit 專屬的一整組捲軸偽元素與偽類別——thumb、track、button、corner 各自對應捲軸的哪個部位,並記錄 Android WebView 內嵌頁面單純用 overflow scroll 捲軸會直接消失、需要額外處理的踩坑。現在標準化的 scrollbar-width/scrollbar-color 屬性整理在新的一篇。

W

調整捲軸的過程中發現對這塊了解不夠,也發現一個奇怪的現象:Android App 內嵌 WebView 時,單純用 overflow: scroll,捲軸反而會消失不見,得額外處理。爬了一輪文整理如下。

捲軸的各個部位

WebKit 系瀏覽器把捲軸拆成好幾個可以個別選取的偽元素:

偽元素對應部位
::-webkit-scrollbar捲軸整體
::-webkit-scrollbar-thumb捲軸裡可以拖動的小方塊(滑塊)
::-webkit-scrollbar-track捲軸的軌道,滑塊在裡面移動
::-webkit-scrollbar-button軌道兩端的按鈕,點一下可以微調滑塊位置
::-webkit-scrollbar-track-piece軌道扣掉滑塊之後剩下的部分
::-webkit-scrollbar-corner水平與垂直捲軸交會處的邊角
::-webkit-resizer邊角處可拖曳調整元素大小的控制元件

常用的偽類別

這些偽元素還能再搭配偽類別,選取更細的狀態:

:horizontal   /* 水平方向的捲軸 */
:vertical     /* 垂直方向的捲軸 */
:decrement    /* 讓捲軸往上或往左移動的按鈕/軌道碎片 */
:increment    /* 讓捲軸往下或往右移動的按鈕/軌道碎片 */
:start        /* 物件位於滑塊之前 */
:end          /* 物件位於滑塊之後 */
:double-button /* 軌道結束處是一對按鈕 */
:single-button /* 軌道結束處是單一按鈕 */
:no-button    /* 軌道結束處沒有按鈕 */
:corner-present /* 邊角是否存在 */
:window-inactive /* 包含捲軸的區域失去焦點時 */

實際範例:

::-webkit-scrollbar-track-piece:start {
  /* 捲軸上半邊或左半邊的軌道 */
}

::-webkit-scrollbar-thumb:window-inactive {
  /* 焦點不在這個區域時,滑塊的狀態 */
}

::-webkit-scrollbar-button:horizontal:decrement:hover {
  /* 滑鼠停在水平捲軸下方按鈕上的狀態 */
}

常見自訂寫法

.scroll-box::-webkit-scrollbar {
  width: 8px;
}
.scroll-box::-webkit-scrollbar-track {
  background: #f1f1f1;
}
.scroll-box::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}
.scroll-box::-webkit-scrollbar-thumb:hover {
  background: #555;
}

Android WebView 裡捲軸消失的踩坑

單純用 overflow: scroll 讓一個區塊可以捲動,一般瀏覽器沒問題,但嵌在某些 Android App 的 WebView 裡,捲軸會直接不見——不是捲動功能壞掉,是捲軸本身沒有畫出來,使用者滑得動但視覺上沒有任何捲軸提示。這是特定 WebView 實作的顯示行為問題,解法通常是額外用上面這組 ::-webkit-scrollbar 系列自己畫一份捲軸樣式,而不是依賴系統預設的捲軸外觀。

現在還用得到嗎

這整組偽元素還能用,Chromium 系瀏覽器都支援,但它們從來不是任何標準規格的一部分,Firefox 完全不認得。想要精細控制捲軸每個部位(滑塊圓角、軌道背景、hover 狀態)依然要靠這一組。如果需求只是「细一點的捲軸」「換個顏色」這種基本調整,現在有標準化的 scrollbar-widthscrollbar-color 屬性,主流瀏覽器引擎都已支援,不需要再依賴 WebKit 專屬寫法,整理在《標準化的捲軸樣式:scrollbar-width 與 scrollbar-color》。

參考資料

分享這篇