HTML制作で気をつけたい
スクロールバーの挙動
- ガタつきをCSSのscrollbar-gutterで防ぐ方法など -

126
180
27

ブラウザのスクロールバーは、OSの種類によって挙動や見た目がさまざまです。環境によって挙動が違うため、自分の環境では問題なくても、ユーザーの環境から見ると問題が起きていることがあります。次のような問題を経験したことがある人も多いのではないでしょうか?

  • 不要なスクロール領域ができていた
  • スクロールバーの切り替わりで画面がガタつく

これらの問題を防ぐためには、対処法のほかにどんな環境で発生するのかを知っておく必要があります。本記事では、スクロールバーの簡単な説明と、2つのよくある問題と対処法について紹介します。

スクロールバーの簡単な説明と、制作時のポイント

よくある問題を紹介する前に、スクロールバーの簡単な説明と、macOSで制作する時の注意点について触れておきたいと思います。

ブラウザのスクロールバーはどのように表示されるのか

HTML/CSSでは、子要素が親要素のボックスからはみだす(オーバーフローを起こす)時の振る舞いをoverflowプロパティで制御しています。この時、overflowプロパティの値がautoまたはscrollだった場合にスクロールバーが表示されます。

※ルート要素のみ特殊で、ブラウザの表示サイズからコンテンツがはみ出る時に、スクロールバーが表示されます。

ボックスにスクロールバーが表示される図

また、スクロールバーはオーバーレイスクロールバーとクラシックスクロールバーの2種類に大きく分類されます。オーバーレイスクロールバーは、スクロールバーの幅を持たずボックスの上に重ねて表示されます。対してクラシックスクロールバーは、ボックスのスペースを削って表示されます。どちらが適用されるかはOSやブラウザによって変化します。

▼macOS: オーバーレイスクロールバーの表示

▼macOS: クラシックスクロールバーの表示

デスクトップのOSだと、Windowsはスクロールバーが常に表示されて、クラシックスクロールバーが通常は適用されます。macOSの場合は、スクロールバーはスクロールした時だけ表示されて、オーバーレイスクロールバーが通常は適用されます。

macOSで制作する時は、クラシックスクロールバーを常に表示しよう

macOSのオーバーレイスクロールバーは、DOM要素にスクロールバーが発生しているかが検知しにくいです。Windows環境のケアが足りず、「あとからWindowsでブラウザを確認をしたら、不要なスクロールバーが表示されていた」ということがよくあります。

そのため、制作時には「常に表示」設定に切り替えて、クラシックスクロールバーを表示しておくことをオススメします。

macOS Ventura 13では、[システム設定]→[外観]にあるスクロールバーの項目から設定を変更できます。通常は「マウスまたはトラックパッドに基づいて自動的に表示」が選択状態となっていて、オーバーレイスクロールが適用されています。「常に表示」を選択すると、クラシックスクロールバーが適用されるようになります。

▼macOS Ventura 13のスクロールバー設定画面

よくある問題①: width: 100vwを指定した時に横スクロールバーが表示される

vwは、ビューポート幅に基づいた割合を指定できる便利な単位ですが、クラシックスクロールバーではルート要素の横幅からスクロールバーの幅分はみだす可能性があります。

ビューポート幅にはスクロールバーの幅も含まれるため、ボックスのスペースを削るクラシックスクロールバーが表示されると、ルート要素の横幅は100vw - スクロールバーの幅となります。そこにwidth: 100vwの子要素を追加すると、ルート要素の横幅からスクロールバーの幅分はみだすという問題が起こります。

次のサンプルは、Y軸方向へスクロール可能なページにwidth: 100%の要素と、width: 100vwの要素を追加しています。クラシックスクロールバーが表示される環境で確認すると、width: 100vw;の横幅はwidth: 100%より大きく、スクロール領域ができていると思います。

▼Windows: 100vwの要素で横スクロールバーが表示されるサンプル

▼macOS: 100vwの要素で横スクロールバーが表示されるサンプル

ルート要素のY軸方向にスクロールが発生する場合は、100vw自体の使いどころが難しくなります。そういった場合はwidth: 100%を利用した実装にするなど、別のアプローチの検討をオススメします。

また、この問題は、macOSなどのオーバーレイスクロールバーが通常は適用される環境だと起きません。HTML制作時には、Windows環境もケアできるように意識しましょう。

よくある問題②: overflow: hiddenの動的切り替えでガタつきが起こる

ルート要素のスクロールを一時的に無効化したい時に、overflow: hiddenを利用するなど、overflowプロパティの値の切り替えを行うことがあります。この切り替えをクラシックスクロールバーで確認すると、スクロールバーの幅分のガタつきが生じてレイアウトシフトが起きます。

次のサンプルは、dialogタグでモーダルを開いた時に、bodyタグにoverflow: hiddenを指定して、スクロールを一時的に無効化したものです。

▼macOS: スクロールバーの幅分がガタつくサンプル

モーダルを開いた時にスクロールはできなくなるものの、クラシックスクロールバーの幅分のレイアウトシフトが起きています。

次のセクションでは、この問題を防ぐ2つの対策を紹介します。

対策①: スクロールバーを常に表示してガタつきを防ぐ

ひとつは、スクロール不可能な時でも、スクロールバーを常に表示する対策です。overflow: scrollposition: fixedを利用して、一時的に「スクロール不可能だけどスクロールバーを常にする」状態を作ります。

この対策はCSSのほかに、JavaScriptの処理が必要になります。作例を用意しましたので、実装の参考にしてみてください。

▼macOS: スクロールバーを常に表示してガタつきを防ぐサンプル

対策②: scrollbar-gutterプロパティでガタつき防ぐ

もうひとつは、scrollbar-gutterというCSSプロパティを利用する対策です。

このプロパティは、スクロールバーの幅分の余白を制御できるプロパティで、スクロールバーが表示されていない状態でもスクロールバーのスペースを確保できます。

次のサンプルでは、モーダルを開くタイミングでbodyタグにoverflow: hiddenを指定しつつ、横幅を制御したい要素にoverflow: autoscrollbar-gutter: stableを指定してガタつきを防いでいます。

▼macOS: scrollbar-gutterプロパティでガタつきを防ぐサンプル

scrollbar-gutterプロパティは、2023年2月現在、ChromeやEdge、Firefoxで利用可能です。Safariでは利用できません。

scrollbar-gutterプロパティのサポート状況

オーバーレイスクロールバーでは、問題が起きないことに注意

スクロールバーがガタつく問題も、「100vwの問題」と同様にmacOS環境だと気付きにくいです。しぶとくお伝えすることになりますが、HTML制作時にはWindows環境もケアできるように意識しましょう。

おまけ: 見た目を変えたい時は-webkit-scrollbar-* / scrollbar-*を利用する

スクロールバーのデザインを調整したい場合、疑似要素::-webkit-scrollbar-*scrollbar-width / scrollbar-colorというCSSプロパティで調整可能です。

Chrome・Safari・Edge用には::-webkit-scrollbar-*を利用し、Firefox用にはscrollbar-width / scrollbar-colorを利用します。

プロパティの詳細は、MDNのドキュメントを参照ください。

次のサンプルは、疑似要素::-webkit-scrollbarscrollbar-colorプロパティを利用して、つまみ部分を赤く装飾したものです。

▼Windows: スクロールバーの装飾サンプル

▼macOS: スクロールバーの装飾サンプル

外観モードにあわせてスクロールバーの配色を変更する

OSの配色を選択できる外観モードには、一般的にはライトモードとダークモードが提供されています。外観モードの配色には、スクロールバーの配色も提供されています。

HTML/CSSでは、metaタグのcolor-schemeを指定することで、OSの設定にあわせたブラウザの配色を利用できます。外観モードをダークにした状態でcolor-schemeを指定すると、スクロールバーは黒ベースな配色に変更されます。

コードは以下のように記述します。

<meta name="color-scheme" content="light dark" />

▼Windows: ダークモードの配色が指定されたスクロールバー

▼macOS: ダークモードの配色が指定されたスクロールバー

また、metaタグのcolor-schemedarkとだけ指定すれば、OSの設定にかかわらず黒い配色のスクロールバーを指定できます。もし暗めのスクロールバーの表示が望ましければ、検討してみてもいいでしょう。

<meta name="color-scheme" content="dark" />

color-schemeの詳細は、MDNのドキュメントを参照ください。

まとめ

スクロールバーの簡単な説明と、よくある問題と対処法について紹介しました。紹介した問題は、オーバーレイスクロールバーでは発生せず、クラシックスクロールバーで起こります。Windows環境ではクラシックスクロールバーが通常は表示されるので、HTML制作時にはWindowsもケアできるように意識しましょう。

参考サイト

古舘 和志

フロントエンドエンジニア。ウェブデザイナーのようなHTMLコーダーからフロントエンドエンジニアに転身。現在は岩手からリモートで勤務中。

この担当の記事一覧