CSSで画面いっぱいに要素を広げたい時、width: 100vw; を使うと、なぜか横スクロールが出て画面がガタついた経験はありませんか?
実はこれ、100vw が「スクロールバーの幅」を含んでしまうことが原因。ブラウザやOSによってスクロールバーの有無や幅が異なるため、CSSだけで完璧に制御するのは至難の業です。
そこで今回は、jQueryを使ってスクロールバーの正確な幅を計測し、CSS変数(カスタムプロパティ)に受け渡す方法を解説します。これさえ覚えれば、もう画面の横揺れに悩まされることはありません!
なぜスクロールバーの幅が必要なのか?(100vwの罠)
多くのブラウザにおいて、100vw はスクロールバーの厚みを含んだサイズを指します。 しかし、コンテンツの表示領域は「100vw – スクロールバーの幅」となるため、単純に 100vw を指定すると、スクロールバーの分だけ要素がはみ出してしまい、不要な横スクロールが発生してしまいます。
この「スクロールバーの幅」をJSで数値として取得できれば、CSS側で計算(calc)に使えるようになり、正確なレイアウトが可能になります。
【重要】スクロールバーの幅を取得するコード
jQueryを使って、目に見えない一時的な要素を作成し、その差分からスクロールバーのサイズを算出します。
$(function() {
/*-------------------------------------------
スクロールバーの幅取得
--------------------------------------------*/
function getScrollbarSize() {
// 1. 一時的なdiv要素を作成して、強制的にスクロールバーを出す
const $div = $("<div></div>")
.css({
position: "absolute",
width: "100px",
height: "100px",
visibility: "hidden",
overflow: "scroll", // 常にスクロールバーを表示
})
.appendTo("body");
// 2. 「コンテンツの外側」と「コンテンツの内側」の差分を計算
const scrollbarWidth = $div.outerWidth() - $div[0].clientWidth;
// 3. 計算が済んだらdiv要素を削除
$div.remove();
return scrollbarWidth;
}
// 実行してCSS変数(--scrollbar-width)に代入
const scrollbarWidth = getScrollbarSize();
$("html").css("--scrollbar-width", scrollbarWidth + "px");
});やっていることの解説
- ダミー要素の作成: 画面外に100pxの正方形を作ります。
- スクロールバーの算出: スクロールバーを除いた内側の幅
clientWidthを引くことで、「スクロールバーの横幅」を割り出します。 - CSS変数へのセット: 取得した数値を
--scrollbar-widthという名前でCSS変数に登録します。
CSS側での使い方
JSから受け取った変数を、CSSの calc() 関数の中で利用します。
:root {
/* 初期値を設定(JSが動く前の保険) */
--scrollbar-width: 0px;
}
.full-width {
/* スクロールバーを除いた、本当の画面いっぱいの幅を計算 */
width: calc(100vw - var(--scrollbar-width));
}このように、100vw からJSで取得した --scrollbar-width を引くことで、どんな環境でもスクロールバーが出ない、ピッタリ画面内に収まるフルワイド要素が作れます。
まとめ
スクロールバーの幅は、WindowsかMacか、あるいはブラウザの設定によってバラバラです。 今回の方法を使えば、環境に左右されず、常に正確な画面幅を計算できるようになります。
ぜひこのテクニックを活用してみてください。


