100vwで画面からはみ出るのはスクロールバーの幅を含むから【解決方法は?】

100vwでページが画面からはみ出る?

コーディングをしていて要素が親要素からはみ出てしまう失敗は初学者のうちはありがちです。

よくある原因として挙げられるのは、widthを絶対値で指定していたり、paddingの扱いをミスしていたりすることです。

これらは調べるとたくさん情報が出てくるので、解決も簡単です。しかし、こうしたよくある失敗に当てはまらず、しかも、原因を確かめようと検証モードにするとはみ出さなくなる現象が生じることがあります。

実は筆者も昔この状態に陥って、原因がなかなかわからずに困ったことがあります。

この記事では、ページが画面からはみ出る現象が発生したら確認したいことと、具体的な解決方法を解説します。

100vwはスクロールバーの幅を含むのでその分画面からはみ出る

結論から言うと、width: 100vw;はスクロールバーの幅を含むので、スクロールバーが表示された閲覧環境だとその分ページが横にはみ出ます。

width: 100vw;を指定することでスクロールバーを含めた画面の横幅いっぱいまで要素が広がり、なおかつスクロールバーの裏側に隠れた部分は画面の外に送られます。

そのため、PCなどスクロールバーが表示されることが多い閲覧環境でwidth: 100vw;を使うと、ページが画面からはみ出してしまうのです。

冒頭で「検証モードで見るとはみ出ない」現象に触れましたが、これは(Chromeの)検証モードの仕様でスクロールバーが常時表示されていないからです。

100vwで画面からはみ出る時の解決方法

解決方法はシンプルで、width: 100vw;を使わないことです。(身も蓋も無いですが)

画面の横幅いっぱいに要素を広げたいのであれば、代わりにwidth: 100%;を使えば(その参照先である親要素に100vwが当たっているなどといった状態でなければ)解決します

また、 理屈上は100vwからスクロールバーの横幅を引けばよいので、width: calc(100vw - calc(100vw - 100%));とすることもできます。しかしわざわざ記述を長くする意義も薄いため、ストレートに100%を使えばよいでしょう。

vw以外の原因ではみ出ている場合

vw以外の原因ではみ出すケースについても解説しておきます。

  • 絶対単位による横幅の指定
  • paddingとborderがからむサイズ計算のミス

絶対単位による横幅の指定

横幅に絶対単位(pxやmmなど固定された大きさを表す単位)を使っていると、画面幅がそれより小さくなると要素がはみ出していきます。

これは非常にシンプルな問題で、例えば下記のように横幅を800pxで指定したとしたら、スマホはそれよりも画面が小さいので、外にはみ出してしまいます。

<div class="box">
    <p>テキストが入ります。テキストが入ります。テキストが入ります。</p>
</div>
.box {
    width: 800px;
}

これは、相対単位(環境条件によって変わる大きさを表す単位)とmax-widthを活用すれば解決できます。

例えば、PCなど1,000pxを超えるような画面で閲覧された時には横幅を800pxにして、小さな画面幅では画面に対して90%の横幅を指定するには下記のようにします。

.box {
    width: 90vw;
    max-width: 800px;
}

このようにすることで、はみ出しを防止することができます。

paddingとborderがからむサイズ計算のミス

初心者の頃はハマりやすい部分かと思いますが、ボックス要素のサイズはデフォルトだとpaddingborderを含みません。

つまり、例えば下記のように記述した場合、横幅は800px + 20px * 2 + 2px * 2 = 844pxになります。

.box {
    width: 800px;
    padding: 20px;
    border: 2px solid #999;
}

これを認識していないと、800pxを指しているつもりで上記のような書き方をしてしまい、結果的に要素が想定よりも大きくなって、画面や親要素からはみ出してしまうことにつながります。

paddingborderを考慮して計算した値を指定する方法もありますが、わずらわしくなるので、多くの場合でbox-sizing: border-box;を使うのがおすすめです。

box-sizing: border-box;を使うと、サイズの計算にpaddingとborderが含まれるようになります

つまり、下記のようにしておくことで、.boxの横幅は844pxではなく800pxになります。

*, *:before, *:after {
    box-sizing: border-box;
}
.box {
    width: 800px;
    padding: 20px;
    border: 2px solid #999;
}
memo

ページ全体で計算方法を統一するために、box-sizing: border-box;はワイルドカードやbodyに対して書いておくのがよいでしょう。

ページが画面からはみ出る現象と解決方法:まとめ

要素がページが画面からはみ出してしまう現象の原因と解決方法を解説しました。内容を振り返ると下記の通りです。

100vw(=スクロールバーも含む)によるはみ出し
100%などで代用
絶対単位での横幅指定によるはみ出し
相対単位やmax-widthを活用
paddingやborderがからむサイズ計算のミスによるはみ出し
box-sizing: border-box; を活用

この記事が参考になれば幸いです。