≪ Today I learned. RSS購読
公開日
タグ
CSS
著者
ダーシノ(@bc_rikko)

スクロールバーとOSの外観設定

ボタン付きのスタック型のコンポーネントで、スタック要素にスクロールバーが表示されるとき、OSの外観設定によってスタイルが崩れてしまう。

以下のようにスクロールバーが表示されることで、Scrollable AreaとButtonの幅がズレてしまう。

+----------------------------+
|           Button           |
+-------------------------+--+
|                         |  |
| <-- Scrollable Area --> |  |
|                         |  |
|                         |  |
|                         |  |
+-------------------------+--+
                 Scrollbar ┘

これはOSの外観設定でスクロールバーの表示/非表示(オーバーレイ)によるものだ。

macOSの外観設定。「スクロールバーを表示」という項目に、「マウスまたはトラックパッドに基づいて自動的に表示」「スクロール時に表示」「常に表示」の選択肢がある。

ブラウザ標準の挙動

「常に表示」の場合は、要素のwidthにスクロールバーの幅が含まれるのに対し、「スクロール時に表示」では含まれない。

▶常に表示の場合
+----------------------------+
|           Button           |
+-------------------------+--+
|                         |  |
| <-- Scrollable Area --> |  |
|                         |  |
|                         |  |
|                         |  |
+-------------------------+--+
                 Scrollbar ┘
▶スクロール時に表示の場合
+----------------------------+
|           Button           |
+----------------------------+
|                            |
| <--- Scrollable Area ----> |
|                            |
|                            |
|                            |
+----------------------------+

scrollbar-gutterを使った場合

scrollbar-gutterプロパティを使うことで、スクロールバーの幅をあらかじめ確保できるが、そうすると「スクロール時に表示」のときに余分なスペースができてしまう。

▶常に表示の場合
+----------------------------+
|           Button           |
+-------------------------+--+
|                         |  |
| <-- Scrollable Area --> |  |
|                         |  |
|                         |  |
|                         |  |
+-------------------------+--+
                 Scrollbar ┘
▶スクロール時に表示の場合
+----------------------------+
|           Button           |
+-------------------------+--+
|                         |
| <-- Scrollable Area --> |
|                         |
|                         |
|                         |
+-------------------------+
           scrollbar-gutter ┘

デモ

  • xxxx
  • xxxx

scrollbar-gutter: autoの場合

スクロールが発生すると内包される要素が縮む

scrollbar-gutter: stableの場合

スクロールが発生する前から内包される要素が縮んでいる

まとめ

ユーザー環境に左右されない実装方法として、scrollbar-width: noneを使ってスクロールバー自体を再実装する方法がある。“技術的には可能”だがなるべくやりたくない手法だ。

したがって、スクロールバーによるコンテンツの幅が変わる現象は「ユーザー環境によるもの」と割り切ってブラウザのデフォルトの挙動に寄せるのが良いと思う。