カスタムスクロールバーを実装したいとき、最初に知りたいのは「結局どんなコードを書けばよいか」だと思います。
まずは実務で使いやすい基本形を示し、そのあとで、なぜその書き方になるのかを整理します。
まずは記述例
.c-scrollbar-custom {
--scrollbar-track-color: var(--color-bg-sub);
--scrollbar-thumb-color: var(--color-theme);
--scrollbar-size: #{rem(14)};
--scrollbar-border-radius: #{rem(10)};
overflow-y: auto;
// height: 100px; // ブロックの高さはエレメント側で指定
}
.c-scrollbar-custom::-webkit-scrollbar {
width: var(--scrollbar-size);
// height: var(--scrollbar-size); // 横スクロールバーの高さを指定する場合
}
.c-scrollbar-custom::-webkit-scrollbar-track {
background: var(--scrollbar-track-color);
border-radius: var(--scrollbar-border-radius);
}
.c-scrollbar-custom::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb-color);
border-radius: var(--scrollbar-border-radius);
}
@-moz-document url-prefix() {
.c-scrollbar-custom {
scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
// scrollbar-width: auto;
}
}
使う側は、スクロールする要素にクラスを付けます。
<div class="c-scrollbar-custom"></div>
なぜこの記述になるのか
理由は単純で、スクロールバーの指定方法がブラウザごとに違うからです。
大きく分けると次の 2 系統です。
- Chrome / Safari / Edge など
::-webkit-scrollbar系の擬似要素で調整する - Firefox
scrollbar-widthとscrollbar-colorで調整する
つまり、1種類の書き方だけで全ブラウザをきれいに揃えるのは難しく、Chrome 系と Firefox 系を分けて書くのが基本になります。
Chrome 系では ::-webkit-scrollbar を使う
Chrome / Safari / Edge では、次のように各パーツごとに指定します。
.c-scrollbar-custom::-webkit-scrollbar {
width: var(--scrollbar-size);
height: var(--scrollbar-size);
}
.c-scrollbar-custom::-webkit-scrollbar-track {
background: var(--scrollbar-track-color);
border-radius: var(--scrollbar-border-radius);
}
.c-scrollbar-custom::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb-color);
border-radius: var(--scrollbar-border-radius);
}
この書き方のよいところは、次のような調整がしやすいことです。
- 幅や高さを個別に指定できる
- トラック色とつまみ色を分けて指定できる
- 角丸の有無も含めて見た目を揃えやすい
Firefox では scrollbar-width / scrollbar-color を使う
Firefox では次のように書きます。
.c-scrollbar-custom {
scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
/* scrollbar-width: auto; */
}
ここで注意したいのは、Firefox の scrollbar-width は
autothinnone
のような指定が中心で、Chrome のように 8px のような任意の幅をそのまま指定できない ことです。
そのため、実務では
- Chrome 系は細かく見た目を指定する
- Firefox は使える指定の範囲で寄せる
のように、完全一致ではなく近い見た目に寄せる 考え方になります。
Firefox 用の指定は分けたほうが安定しやすい
Firefox 用のつもりで、標準プロパティをそのまま書くと、Chrome 側の見た目に影響することがあります。
@-moz-document url-prefix() {
.c-scrollbar-custom {
scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
/* scrollbar-width: auto; */
}
}
環境によっては、Chrome 側でもこの指定が解釈されて、ネイティブ寄りの見た目に寄ってしまう ことがあります。
その結果、::-webkit-scrollbar で整えた見た目とズレて、丸みが付いたように見えることがあります。
そのため、Chrome 側の見た目を優先したいなら、Firefox 用は @-moz-document の中に分けた方が扱いやすくなります。
component として持つ考え方
スクロールバー装飾を親コンテキストから調整する前提なら、単なる utility よりも、小さな見た目部品 として持つ方が自然です。
たとえば、
u-scrollbar-custom
よりも、
c-scrollbar-custom
の方が、責務としてわかりやすいことがあります。
まとめ
カスタムスクロールバーを実装するときは、まず今回のコードを基本形として持っておくと整理しやすいです。
- Chrome / Safari / Edge は
::-webkit-scrollbar - Firefox は
scrollbar-width/scrollbar-color - Firefox 用の標準プロパティは必要に応じて分ける
スクロールバーはブラウザ差が大きいので、全ブラウザで完全一致を狙うより、破綻しない形で近づける という考え方の方が実務向きです。