::-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-width/scrollbar-color 屬性,主流瀏覽器引擎都已支援,不需要再依賴 WebKit 專屬寫法,整理在《標準化的捲軸樣式:scrollbar-width 與 scrollbar-color》。