CSSのみでスクロールバーの幅を取得する方法
コンテナクエリ単位の登場により、これまでJavaScriptに頼ることが多かった計算も、CSSだけで行えるようになってきました。
この記事では、その仕組みを使ってCSSのみでスクロールバーの幅を取得する方法を紹介します。
最小構成
CSSのみでスクロールバーの幅を取得するための最小構成です。
@property --scrollbar-width {
syntax: "<length>";
inherits: true;
initial-value: 0px;
}
html {
container-type: inline-size;
}
body {
--scrollbar-width: calc(100vw - 100cqi);
}ポイントは、100vwとコンテナクエリ単位の100cqiを比較している点です。
(※cqiの代わりにcqwでも可)
100vwはスクロールバーを含んだビューポート幅、100cqiはスクロールバーを除いた表示領域の幅になるため、その差分がスクロールバーの幅になります。
ここではその差を--scrollbar-widthというカスタムプロパティに格納しています。
フルブリードレイアウトのデモ
スクロールバーの幅が必要になる代表的なケースとして、親要素の幅を超えて画面幅いっぱいに表示するフルブリードレイアウトが挙げられます。
See the Pen CSSのみでスクロールバーの幅取得 by hisa (@hisaaashi) on CodePen.
単純に100vwを指定した場合は、横スクロールが発生してしまいますが、スクロールバーを考慮して計算すると画面幅ぴったりに収めることができます。
とはいえ…
フルブリードレイアウトの実装ならcqiをそのまま使うこともできます。
html {
container-type: inline-size;
}
body {
--fullwidth-half: 50cqi;
}
.fullwidth-section {
margin-inline: calc(50% - var(--fullwidth-half));
}See the Pen CSSのみでスクロールバーの幅取得 by hisa (@hisaaashi) on CodePen.
ただし、コンテナクエリ単位は「最も近い祖先のコンテナ」 を基準とするので、上記アプローチはコンテナ要素がネストしていないことが条件です。
html {
container-type: inline-size;
}
body {
--fullwidth-half: 50cqi;
}
main {
container-type: inline-size; /* ネスト */
max-width: 600px;
margin-inline: auto;
}
.fullwidth-section {
/* 🙅 main 要素の 50cqi を基準に計算される */
margin-inline: calc(50% - var(--fullwidth-half));
}コンテナクエリの注意点
コンテナクエリは強力ですが、古いバージョンのブラウザではいくつかのバグが報告されています。
- コンテナ要素の子孫要素で
position: fixedが効かずabsoluteとして扱われる - Safariでhtml要素に指定した
container-typeが正しく機能しない
現在この問題は改善されていますが、必要に応じてフォールバックを用意するか、あるいは最新のOSやブラウザのみを対象として要件定義しておいた方が安全です。
まとめ
CSSだけでスクロールバーの幅を取得する方法の解説でした。
JavaScriptを使用しない一つの選択肢として覚えておくと便利です。

カスタマイズに困ったらお気軽にご相談を!
- 「ちょっとしたCSSの調整だけお願いしたい」
- 「不具合を直してほしい」
料金は3,000円〜、お支払いは銀行振込・Amazonギフトカードなど柔軟に対応してます🤔
お気軽にコメントどうぞ