スクロールバーのカスタマイズは『Simplebar』を使えばだいたい解決すると思ったので使い方を紹介する試み
スクロールバーの見た目を変えたいと思ったことはないでしょうか?
どのデバイスでも同じ見た目にしたいという願望が多そうですが、私はサイト全体で縦方向のスクロールバーのツマミ部分(::-webkit-scrollbar-thumbで調整できる部分)の高さを固定したくてcssだけで調整できないかと四苦八苦して、ChatGPTに聞いてもうまくいかないので『Simplebar』というjsのライブラリを使って解決しました。
この記事ではブラウザのデフォルトのスクロールバーをカスタムできるjsライブラリ『simplebar』の使い方を紹介していきます
この記事の目次
Simplebarとは
『Simplebar』は前述した通りブラウザのデフォルトのスクロールバーをカスタムできるjsライブラリです
JavaScriptを使ったスクロールバーをカスタマイズできる高性能なライブラリはいくつかありますが、JavaScriptでスクロールを制御しようとすると不自然な動きになることがあります
『Simplebar』はスクロールをJavaScriptで制御しないので動きは元々のスクロールバーの動きを維持したままカスタマイズできます
日本で有名なサイトだとtwitchというストリーミングサイトでも採用されているので、信頼性も高いです
Simplebarの使い方を紹介する前に…
コードとかの前に今回紹介するShimplebarはbody要素に対して使うことを推奨されていません(textarea・table・iframeも非推奨)
UXで悪影響を及ぼすので公式サイトの方で上記の要素で使いたいなら他のライブラリを使うか自己責任で行ってくださいとアナウンスされています
ちょっとしたデメリットが出ますが自己責任で使いたい人々のためにサイト全体のスクロールバーをカスタマイズする方法を紹介していきます
Simplebarを使ってみる
SimplebarについてはGithubの方で詳しく紹介されていますのでこちらもご覧ください
Simplebarのライブラリを読み込む
Simplebarはライブラリなのでインストールや読み込まないと使えません、 いくつかの方法がありますので紹介しておきます
1 |
npm install simplebar resize-observer-polyfill --save |
1 |
yarn add simplebar resize-observer-polyfill |
1 2 3 4 5 |
<link rel="stylesheet" href="https://unpkg.com/simplebar@latest/dist/simplebar.css"/> <script src="https://unpkg.com/simplebar@latest/dist/simplebar.min.js"></script> <!-- or --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/simplebar@latest/dist/simplebar.css"/> <script src="https://cdn.jsdelivr.net/npm/simplebar@latest/dist/simplebar.min.js"></script> |
この記事ではCDNで読み込んで使う方法でSimplebarの使い方を紹介していきます
head要素に諸々のコードを埋め込む
これがないと一切動かないのでライブラリを読み込むコードをhead要素に埋め込んでいきます
noscriptへ対応するためのコードも提供されているのでnoscript要素も一緒に埋め込んでおきましょう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Simplebar</title> <link rel="stylesheet" href="https://unpkg.com/simplebar@latest/dist/simplebar.css" /> <link rel="stylesheet" href="style.css"> <script src="https://unpkg.com/simplebar@latest/dist/simplebar.min.js"></script> <noscript> <style> /** * Reinstate scrolling for non-JS clients */ .simplebar-content-wrapper { scrollbar-width: auto; -ms-overflow-style: auto; } .simplebar-content-wrapper::-webkit-scrollbar, .simplebar-hide-scrollbar::-webkit-scrollbar { display: initial; width: initial; height: initial; } </style> </noscript> </head> |
Shimplebarをdata属性で使う
Shimplebarを使う方法の一つとしてdata属性を使う方法があり、いろんなブログとかで紹介されている使い方がこれなんだけどカスタマイズしたりするときには正直不向きかな?と思う
ただ使うだけであればこの方法が簡単で、オプションもdata属性として設定できるので、開始タグがゴチャつくことに抵抗がなかったり、あまりオプションを使わないよって人にはこの方法をおすすめします
1 2 3 |
<body data-simplebar> <!--オプションを使う時--> <body data-simplebar data-simplebar-オプション名="値"> |
Shimplebarをコードを書いて使う
data属性を使って使用する方法は簡易的に使う分には十分だったりしますが、オプションをいくつか設定したり、複数要素に一括で指定したりするときにはバチクソ不便です
書き方は余り難しくないと言うかscript要素の中にコピペして対象の要素を変えるだけなんでこっちのやり方のほうが断然使いやすいと思ふ
querySelectorでbody要素を取得しているけどidつけてgetElementByIdを使ってもOK
1 2 3 4 5 6 7 |
const simpleBar = new SimpleBar(document.querySelector('body')); //オプションを使う時 const simpleBar = new SimpleBar(document.querySelector('body'), { オプション: 値, オプション: 値 }); |
この記事ではそこまで掘り下げませんが、複数の要素に対して実行したい場合はちょっと書き方が変わって以下のように書きます(クラスscrollが付いた要素に対してという想定のコード)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Array.prototype.forEach.call( document.querySelectorAll('.scroll'), (el) => new SimpleBar(el) ); //オプションを使う時 Array.prototype.forEach.call( document.querySelectorAll('.scroll'), (el) => new SimpleBar(el, { オプション: 値, オプション: 値 }) ); |
cssをちょこっと調整する
とりあえず公式の言う通りの使い方をしていればここまででスクロールバーが変わってくるけど、body要素に対して使った場合はこのままではスクロールバーが変わらないはずなのでcssをちょこっと調整する必要があります
とはいえ高さをデバイスと同じに固定するだけなんで難しい調整は一切ないと思います
1 2 3 4 |
body { height: 100vh; height: 100dvh; } |
とりあえずここまでのデモページとコードをまとめておきます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>scrollbartest</title> <link rel="stylesheet" href="https://unpkg.com/simplebar@latest/dist/simplebar.css" /> <link rel="stylesheet" href="style.css"> <script src="https://unpkg.com/simplebar@latest/dist/simplebar.min.js"></script> <noscript> <style> /** * Reinstate scrolling for non-JS clients */ .simplebar-content-wrapper { scrollbar-width: auto; -ms-overflow-style: auto; } .simplebar-content-wrapper::-webkit-scrollbar, .simplebar-hide-scrollbar::-webkit-scrollbar { display: initial; width: initial; height: initial; } </style> </noscript> </head> <body> <div> <div class="content"></div> <div class="content"></div> <div class="content"></div> <div class="content"></div> <div class="content"></div> </div> <script> const simpleBar = new SimpleBar(document.querySelector('body')); </script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 |
body { margin: 0; height: 100vh; height: 100dvh; } .content { height: 100vh; background-color: #d4f6ff; } .content:nth-child(even) { background-color: #89d4ff; } |
Shimplebarのオプション
オプションに関しても公式のgithubの方で紹介されているのでそちらをみたほうが早そうですが、紹介しているところがなさそうなので紹介しておきます
以下のコードのようにイニシャライズのコードに追加して使う方が使いやすいと思われるのでこっちの方法で紹介していきます
1 2 3 4 |
const simpleBar = new SimpleBar(document.querySelector('body'), { オプション: 値, オプション: 値 }); |
data属性を使う場合ではオプション名が変わるのであまり紹介されていないんだろうと思うんですけど、ケバブケースに変えればdata属性で使えますのでどうしてもdata属性で使いたいのであればうまく対応してください
autoHide
Shimplebarのデフォルトでは、ユーザーがスクロールしていない場合、自動的にスクロールバーを隠す動きをしてくれます。
autoHideオプションをfalseに設定することで、スクロールバーを常に表示するようにすることができます。
1 2 3 |
const simpleBar = new SimpleBar(document.querySelector('body'), { autoHide: false //スクロールバーを常に表示 }); |
scrollbarMinSize/scrollbarMaxSize
スクロールバーのつまみの部分の最小サイズを指定するscrollbarMinSize(デフォルトは10という説と25と言う説がありますが25です)とスクロールバーのつまみの部分の最大サイズを指定するscrollbarMaxSize(デフォルトは0 ←無制限らしい)を調整するとスクロールバーの大きさをカスタマイズでき、どちらもピクセル単位になるのですが値にはpxはつけずに数値だけで指定します
両方とも同じにすればどんなときでも同じ大きさにするという記事の冒頭で紹介した私がやりたかったことがうまくできました
cssでもいじれますが、スクロールバーの挙動がおかしくなるのでこれで調整してください
1 2 3 4 |
const simpleBar = new SimpleBar(document.querySelector('body'), { scrollbarMinSize: 60, //つまみの部分の最小サイズを60pxに指定 デフォルトは10 scrollbarMaxSize: 60 //つまみの部分の最大サイズを60pxに指定 デフォルトは0で無制限らしい }); |
data属性で使う場合はケバブケースにして以下のように指定します
1 |
<body data-simplebar data-simplebar-scrollbar-min-size="60" data-simplebar-scrollbar-max-size="60"> |
classNames
SimpleBarが使用するデフォルトのクラス名を変更するためのオプションで、変えられるものが公式の発表では4種類用意されていますが、この記事を書いている現在では全部変えられるみたいです
デフォルトのcssを使いつつオーバーライドさせて見た目の調整をする方法が簡単だと思いますが、まるっきり違うものにしたい場合はいいかもしれません
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
const simpleBar = new SimpleBar(document.querySelector('body'), { classNames: { //以下が変えられるもので値はデフォルト値 contentEl: "simplebar-content", contentWrapper: "simplebar-content-wrapper", offset: "simplebar-offset", mask: "simplebar-mask", wrapper: "simplebar-wrapper", placeholder: "simplebar-placeholder", scrollbar: "simplebar-scrollbar", track: "simplebar-track", heightAutoObserverWrapperEl: "simplebar-height-auto-observer-wrapper", heightAutoObserverEl: "simplebar-height-auto-observer", visible: "simplebar-visible", horizontal: "simplebar-horizontal", vertical: "simplebar-vertical", hover: "simplebar-hover", dragging: "simplebar-dragging", scrolling: "simplebar-scrolling", scrollable: "simplebar-scrollable", mouseEntered: "simplebar-mouse-entered" } }); |
data属性で使う方法は見つからなかったです
forceVisible
forceVisibleオプションを使用すると、トラックを強制的に表示させることができるらしいです
cssでいうoverflow: scrollと同じ動作らしいですが、この記事を書いている現在ではうまく働きません
1 2 3 |
const simpleBar = new SimpleBar(document.querySelector('body'), { forceVisible: true | 'x' | 'y' //スクロールバーのツマミ部分を常に表示 デフォルトはfalse }); |
data属性で使う場合はケバブケースにして以下のように指定すると思われますがうまく動作してくれないのでなんとも言えない感じです
1 |
<body data-simplebar data-simplebar-force-visible="true"> |
direction
rtlサポートを有効にすることができます
1 2 3 |
const simpleBar = new SimpleBar(document.querySelector('body'), { direction: 'rtl' //デフォルトは'ltr' }); |
data属性で使う場合はケバブケースにして以下のように指定します
1 |
<body data-simplebar data-simplebar-direction="rtl"> |
clickOnTrack
トラックのつまみがない部分をクリックしたときの挙動を指定することができるオプションです
デフォルトはtrueなのでスクロールバーのつまみの上下にあるスペースをクリックするとスクロールしてくれますが、falseにすると無反応になります
1 2 3 |
const simpleBar = new SimpleBar(document.querySelector('body'), { clickOnTrack: false //デフォルトはtrue }); |
data属性で使う場合はケバブケースにして以下のように指定します
1 |
<body data-simplebar data-simplebar-click-on-track="false"> |
以上で公式から紹介されているオプションの紹介はおしまいです
cssを使って見た目を変える
この辺はデベロッパーツールを使って調整できると思うんですけどとりあえずいじりたくなりそうな部分だけ抜粋して紹介しておきます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* スクロールバーのツマミ部分の色を変えたい時 */ .simplebar-scrollbar::before { background: linear-gradient(151deg, #60c5ff, #31ffad, #31e4ff); //デフォルトはblack } /* スクロールバーのツマミ部分の不透明度とhover時のtransitionを変えたい時 */ .simplebar-scrollbar.simplebar-visible:before { opacity: 1; //デフォルトは0.5 transition-duration: 0.2s; //デフォルトは0s; } /* スクロールバー太さを変えたい時 */ .simplebar-track.simplebar-vertical { width: 20px; //デフォルトは11px } |
以上
あまり変更点はないけど最終的なコードとデモをどうぞ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>scrollbartest</title> <link rel="stylesheet" href="https://unpkg.com/simplebar@latest/dist/simplebar.css" /> <link rel="stylesheet" href="style.css"> <script src="https://unpkg.com/simplebar@latest/dist/simplebar.min.js"></script> <noscript> <style> /** * Reinstate scrolling for non-JS clients */ .simplebar-content-wrapper { scrollbar-width: auto; -ms-overflow-style: auto; } .simplebar-content-wrapper::-webkit-scrollbar, .simplebar-hide-scrollbar::-webkit-scrollbar { display: initial; width: initial; height: initial; } </style> </noscript> </head> <body> <div> <div class="content"></div> <div class="content"></div> <div class="content"></div> <div class="content"></div> <div class="content"></div> </div> <script> const simpleBar = new SimpleBar(document.querySelector('body'), { scrollbarMinSize: 60, scrollbarMaxSize: 60 }); </script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
body { margin: 0; height: 100vh; height: 100dvh; } .content { height: 100vh; background-color: #d4f6ff; } .content:nth-child(even) { background-color: #89d4ff; } .simplebar-scrollbar::before { background: linear-gradient(151deg, #60c5ff, #31ffad, #31e4ff); } .simplebar-scrollbar.simplebar-visible:before { opacity: 1; transition-duration: 0.2s; } .simplebar-track.simplebar-vertical { width: 20px; } |
最後にデメリットのこと
UXで悪影響を及ぼすってことを前述しましたがいくつか気づいた点をリストアップしておきます
- iosのステータスバーで一番上までスクロールする機能がなくなる
- トラックをクリックしたときの動作がデフォルトと比べると遅い
ウインドウサイズによって切り替えたりしたらステータスバーの件は解決できそうだけど、そもそもスマホとPCのスクロールバーを統一するって目的もあるから他のものを使うか諦めるしかなさそう
ステータスバーの機能を知っているユーザー多いのかな?スマホでもTOPへ戻るボタンよく見るし判断がつかない
デフォルトと比べると遅い動作は個人的に気にはならないけど神経質な人は気になるんだろうな~ってレベル
使用は自己判断でってことだったのであとは使い手が判断してください