スクロールバーとOSの外観設定
ボタン付きのスタック型のコンポーネントで、スタック要素にスクロールバーが表示されるとき、OSの外観設定によってスタイルが崩れてしまう。
以下のようにスクロールバーが表示されることで、Scrollable AreaとButtonの幅がズレてしまう。
+----------------------------+
| Button |
+-------------------------+--+
| | |
| <-- Scrollable Area --> | |
| | |
| | |
| | |
+-------------------------+--+
Scrollbar ┘
これはOSの外観設定でスクロールバーの表示/非表示(オーバーレイ)によるものだ。
ブラウザ標準の挙動
「常に表示」の場合は、要素の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を使ってスクロールバー自体を再実装する方法がある。“技術的には可能”だがなるべくやりたくない手法だ。
したがって、スクロールバーによるコンテンツの幅が変わる現象は「ユーザー環境によるもの」と割り切ってブラウザのデフォルトの挙動に寄せるのが良いと思う。