Last updated on

カスタムスクロールバーを実装するときの基本コード

  • CSS
  • Sass
  • Scrollbar
  • Firefox
  • Chrome

カスタムスクロールバーを実装したいとき、最初に知りたいのは「結局どんなコードを書けばよいか」だと思います。
まずは実務で使いやすい基本形を示し、そのあとで、なぜその書き方になるのかを整理します。

まずは記述例

.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-widthscrollbar-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

  • auto
  • thin
  • none

のような指定が中心で、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 用の標準プロパティは必要に応じて分ける

スクロールバーはブラウザ差が大きいので、全ブラウザで完全一致を狙うより、破綻しない形で近づける という考え方の方が実務向きです。