scrollbar-gutter CSS プロパティでスクロールバーの切り替わりによる画面のガタツキを解消する
子要素が親要素のボックスからはみ出した時、overflow プロパティの値が auto または scroll の場合にスクロールバーが表示されます。スクロールバーがクラシックスクロールバーの場合、スクロールバーの表示・非表示によりボックスの幅が変わるため、画面がガタつくことがあります。scrollbar-gutter プロパティを使うとスクロールバー用のスペースをあらかじめ確保でき、画面のガタツキを解消できます。
子要素が親要素のボックスからはみ出した時、overflow
プロパティの値が auto
または scroll
の場合にスクロールバーが表示されます。スクロールバーがどのように表示されるかは OS やブラウザの設定により異なりますが、大きく分けて以下のような挙動があります。
- オーバーレイスクロールバー:スクロールバー自体が幅を持たず、スクロール領域に重なって表示される
- クラシックスクロールバー:スクロールバーが幅を持ち、スクロール領域を狭めて表示される
例として MacOS の場合では、デフォルトでオーバーレイスクロールバーが採用されています。システム環境設定で「外観 > スクロールバーを表示」を「常に表示」に設定することでクラシックスクロールバーに変更できます。
クラシックスクロールバーの場合、スクロールバーの有無によりボックスの幅が変わるため、スクロールバーの表示・非表示が切り替わるたびに画面がガタつくことがあります。
以下の例では、「追加」ボタンを押すたびにリストが追加され、ボックスの height を超えたタイミングでスクロールバーが表示されテキストがずれていることが確認できます。
scrollbar-gutter プロパティでガタツキを解消する
scrollbar-gutter
プロパティを使うとスクロールバー用のスペースをあらかじめ確保できます。つまり、スクロールバーが表示・非表示に切り替わってもボックスの幅が変わらなくなるのです。先程の例に scrollbar-gutter
プロパティを追加してみましょう。scrollbar-gutter
プロパティの値に stable
を指定することで、子要素が親要素のボックスをはみ出ない場合でもスクロールバー用のスペースを確保します。
scrollbar-gutter: stable
を指定されたときにあらかじめスペースが確保されるのは、クラシックスクロールバーの場合のみです。
.box {
scrollbar-gutter: stable;
}
scrollbar-gutter: stable
を指定した場合、ボックスの右側にのみスクロールバー用のスペースが確保されるため、コンテンツが左側に偏って配置されているように見えてしまいます。
このような場合、scrollbar-gutter
プロパティに stable both-edges
を指定することで、ボックスの両側に対称的なスペースを確保できます。
.box {
scrollbar-gutter: stable both-edges;
}
オーバーレイスクロールバーの場合
scrollbar-gutter: stable
であらかじめスクロールバー用のスペースを確保されるのは、クラシックスクロールバーの場合のみです。オーバーレイスクロールバーの場合には scrollbar-gutter
を指定していない時と同じ挙動になります。オーバーレイスクロールバーの場合はスクロールバーがスクロール領域に重なって表示されるため、スクロールバー用のスペースを確保する必要がないためです。
MacOS のスクロールバーの表示の設定を「マウスまたはトラックパッドに基づいて自動的に表示」に切り替えると、scrollbar-gutter: stable
を指定したとしてもスクロールバー用のスペースが確保されないことが確認できます。
まとめ
- スクロールバーの種類にはスクロールバー自体が幅を持たず、スクロール領域に重なって表示されるオーバーレイスクロールバーと、スクロールバーが幅を持ち、スクロール領域を狭めて表示されるクラシックスクロールバーがある
- クラシックスクロールバーの場合、スクロールバーの表示・非表示によりボックスの幅が変わるため、画面がガタつくことがある
scrollbar-gutter: stable
を指定するとスクロールバー用のスペースをあらかじめ確保でき、スクロールバーの表示・非表示による画面のガタツキを解消できるscrollbar-gutter: stable both-edges
を指定するとボックスの両側に対称的なスペースを確保できるscrollbar-gutter: stable
であらかじめスペースが確保されるのは、クラシックスクロールバーの場合のみで、オーバーレイスクロールバーの場合はスペースが確保されない