CSSの100vwで水平スクロールバーが表示される問題がようやく解決! vwにスクロールの幅が含まれなくなります

Web制作者の長年の悩みがようやく解決されます!

CSSで100vwを使用して幅いっぱいにすると、垂直のスクロールバー分が含まれて、水平スクロールバーが表示されてしまいます。この問題はWindowsで起こり、macOSでもクラシックのスクロールバーを使用していると起こります。

Chromeの次のバージョンである145では、vwのサイズに垂直スクロールバーの幅が認識されるようになり、100vwにした場合スクロールバーの幅のサイズを含まずに幅いっぱいとして機能するようになります。

まずはChromeのみですが、CSSワーキンググループで議決されたので、他のブラウザも随時サポートすると思います。

100vwを使用するとスクロールバーが認識されるようになりました

Using 100vw is now scrollbar-aware
by Bramus!

下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

はじめに

Chromeは145以降、html要素に垂直スクロールバーを常に表示するように設定した場合(overflow[-y]: scroll;)、またはスクロールバー用のスペースを確保した場合(scrollbar-gutter: stable;)、100vw自動的に垂直スクロールバーの幅のサイズを差し引きます。

これは水平スクロールバーのvh、そしてSmall, Large, Dynamicのバリエーションにも同様の処理が適用されます。

関連して「高さいっぱい」のvhについては下記をご覧ください。

CSSの新しい単位(lvh, svh, dvh)がすべてのブラウザでサポート、100vhがビューポートの高さいっぱいにならない問題を解決

100vwが幅いっぱいを超えてしまう問題

CSSのビューポート単位(vwなど)の問題点は、これらの単位が従来のスクロールバーの存在を考慮していないことです。そのため、幅を100vwに設定すると、ビューポートの幅全体を占めるようにサイズが調整されます。これにより垂直スクロールバーが存在する場合にオーバーフローが発生する可能性があります。

下記のスクリーンショットでは、ブルーのボックスの幅を100vwに設定しています。垂直スクロールバーが存在するため(ビューポートの最終的な幅を狭める)、ブルーのボックスは「スクロールバーを考慮したビューポート」内には収まりきらず、水平スクロールバーも表示されて、両方向にオーバーフローされます。

サイトのキャプチャ

デモページをChrome 144で表示したスクリーンショット

水平スクロールバーが表示されていることに注目してください。
※macOSでクラシックのスクロールバーにしています。

この無意味な水平スクロールバーについては、2021年にŠime VidasがCSSワーキング グループにこの問題を提出しました。

なぜこの問題の解決が難しいのか

この無意味な水平スクロールバーの問題に対しては、さまざまな反応がありました。主なものは「CSSが愚かで、ビューポート単位はスクロールバーの存在を考慮すべきだ」です。しかし、この問題はそう簡単に解決するものではありませんでした。

たとえば、100vw * calc(100vh + 1px)のサイズを持つボックスのみを含むページがあるとします。従来のスクロールバーでは、ページは両方向にオーバーフローしてしまいます。この場合vw単位がスクロールバーのサイズを減算して調整すると、下記のような悪循環に陥ってしまいます。

  1. ページは垂直方向にオーバーフローします(calc(100vh + 1px)のため)
  2. オーバーフローしているので、ブラウザは垂直スクロールバーを表示します
  3. ページは水平方向にもオーバーフローします(100vwのため)
  4. ブラウザは両軸のビューポート単位からスクロールバーのサイズを差し引きます
  5. ページは水平方向にオーバーフローしなくなります
  6. ブラウザは水平スクロールバーを表示しなくなります
  7. 結局ブラウザはvh単位からスクロールバーのサイズを差し引かなくなります
  8. 1に戻る

つまり、単純にスクロールバーのサイズ分を減らすだけでは、実行可能な解説策にはなりません。

常に表示されるスクロールバー(またはスクロールバーガター)

Firefoxがかつて実装していた機能(後に相互運用性がないとして削除)は、vw単位からスクロールバーのサイズを差し引く処置でした。ただし、これはページが常にスクロールバーを表示するように設定されている場合(overflow-y: scroll;)にのみ適用されていました。

確かにこの解決方法は機能します。なぜなら、垂直スクロールバーの存在は条件付きではなく、常に表示されるからです。

  1. ブラウザは、ページが現在オーバーフローしているかどうかにかかわらず、垂直スクロールバーを表示します
  2. vw単位からスクロールバーのサイズを差し引きます
  3. 水平スクロールバーを表示する必要はありません

CSSワーキンググループは2023年末、この解決策を決定しました。

解決済み: ルート要素にoverflow: scroll;が設定されている場合(body要素から伝播されない場合)、vwのサイズにデフォルトのスクロールバーの幅を考慮する。

つまり、html要素にoverflow-y: scroll;を宣言した場合、100vwの値を決定する際に垂直スクロールバーのサイズが考慮されるということです。vh単位と水平スクロールバーについても同じです。

さらに興味深いのは、CSSワーキンググループがこの動作のトリガーとして(ルートにある)scroll-gutter: stable;も考慮に入れることを決議したことです。

また、ルートではscrollbar-gutterも考慮します。

html要素に対してoverflow-y: scroll;を設定するよりも、scrollbar-gutter: stable;を設定することをお勧めします。

なぜなら、overflow-y: scroll;は不要な場合でも常にスクロールバーを表示してしまうからです。

CSSリセットに記述していない場合は、下記を追加してください。

既存のWebサイトに支障が出るのでは

当初の解決策が採用された後も、既存のWebサイトに支障が出るのではという議論が繰り返されました。すでに手動でスクロールバーのサイズを100vwから差し引いている場合、視覚的に支障が出るからです。

The HTTP Archivecalc(100vw - var(--scrollbar-width))が使用されているサイトがどれだけあるか2024年の当時に調べてみました。

The HTTP Archiveに登録されていたのは12,089,606のルートページで、その結果は下記の通りです。

  • 324,866ページがcalc(100vw - var(--scrollbar-width))を使用(2.68%)
  • 4,112ページがルート要素にoverflow: scroll;を設定(0.03%)
  • 72ページがその両方を使用(0.0005%)

72ページのうち、スクロールバーに対応するためにcalc()を使用しているのは38ページのみです。それ以外の34ページは<length>50pxを超える計算を行っていましたが、スクロールバーがそのような幅を持つことは考えにくいでしょう。

この数字は十分に小さいと言えるため、この互換性のない変更を導入する正当性が認められます。特にデータ損失につながらず、この変更を使用しているオリジンが上位の1000サイトに含まれていないことを考慮し、CSSワーキンググループは2024年半ばにこの計画を継続する第二の決議を行いました。

Chrome 145でスクロールバー対応のビューポート単位が利用可能に

この問題に関するCrBugは去年割り当てられ、CLは修正のための続いたことを嬉しく思いました(Davidありがとう!)。必要なCLはすべて2025年12月にマージされ、2025年の最終日にこの問題は修正済みにマークされました🎉

そして先日リリースされたChrome 145ベータ版に、この変更が含まれています。
ドキュメントのスクロールバーが反対軸に強制表示される場合、またはスクロールバー用のスペースが確保されている場合、ビューポート単位はスクロールバーを認識するようになりました。

Chrome 145で前述のデモを表示すると、下記のように「不要なスクロールバーはなし」で表示されます。

サイトのキャプチャ

デモページをChrome 145で表示したスクリーンショット

水平スクロールバーが表示されていないことに注目してください。

sponsors

top of page

©2026 coliss