width: 100%を指定したのに、要素が親の横幅からはみ出す。原因はwidthそのものではなく、padding・border・margin・最小幅・長いコンテンツなどが、計算後の横幅へ追加されていることです。
この記事では、width:100%でも横スクロールが発生する代表的な原因を7つに分け、DevToolsでの調査方法と修正例を解説します。
width:100%の基準
パーセントのwidthは、基本的に包含ブロックの幅を基準に計算されます。初期値のbox-sizing: content-boxでは、100%になるのは内容領域だけで、paddingとborderはその外側へ追加されます。
.child {
width: 100%;
padding: 24px;
border: 4px solid;
/* 実際の外幅は親幅 + 48px + 8px */
}原因1:paddingとborderが幅へ追加されている
最も多い原因です。box-sizing: border-boxを指定すると、paddingとborderを100%の内側へ含められます。
*,
*::before,
*::after {
box-sizing: border-box;
}原因2:左右のmarginが追加されている
width: 100%に左右marginを足すと、その分だけ親より広くなります。中央寄せが目的なら、固定幅またはmax-widthとmargin-inline: autoを組み合わせます。
/* はみ出す */
.box {
width: 100%;
margin-inline: 20px;
}
/* 親側に余白を持たせる */
.parent {
padding-inline: 20px;
}
.box {
width: 100%;
}原因3:100vwを使っている
100vwはviewport幅を基準にします。環境によっては縦スクロールバーの幅も含むため、ページ本文で使うと数pxの横スクロールが出ることがあります。また、親要素のpaddingも無視します。
/* ページ内コンテンツならこちらが安全 */
.section {
width: 100%;
}
/* 画面幅基準が本当に必要な時だけ */
.full-bleed {
width: 100vw;
}原因4:Flexboxの子要素が縮まない
Flexアイテムは内容の最小幅を維持しようとします。長いURL、コード、画像などがある場合、width:100%の内側でも親を押し広げます。縮ませたいFlexアイテムへmin-width: 0を指定します。
.layout {
display: flex;
}
.main {
flex: 1;
min-width: 0;
}原因5:Gridの1frが最小コンテンツ幅を維持している
Gridの1frも、内容の最小幅によって列が広がることがあります。可変列をminmax(0, 1fr)にします。
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 280px;
gap: 32px;
}原因6:画像・iframe・preに最大幅がない
画像や埋め込みコンテンツが親より大きい固定幅を持つと、親要素がwidth:100%でも中身がはみ出します。
img,
video,
iframe {
max-width: 100%;
}
pre {
max-width: 100%;
overflow-x: auto;
}原因7:長いURLや英単語が折り返されない
自然な改行位置を持たない文字列は、要素の最小幅を大きくします。URLやユーザー入力を表示する場所では折り返し規則を明示します。
.content {
overflow-wrap: anywhere;
}
/* 古い実装との互換が必要なら */
.content {
word-break: break-word;
}CodePen埋め込み用エリア
以下をCodePenへ貼ると、content-boxでpaddingが追加される例と、border-boxによる修正、長いURL対策を比較できます。
HTML
<main class="width-demo">
<section class="case">
<h2>はみ出す例</h2>
<div class="box box--bad">width: 100% + padding</div>
</section>
<section class="case">
<h2>修正例</h2>
<div class="box box--good">box-sizing: border-box</div>
</section>
<section class="case">
<h2>長い文字列</h2>
<div class="long-text">https://example.com/this-is-a-very-long-url-without-natural-break-points</div>
</section>
</main>CSS
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 24px;
background: #f2f2f2;
color: #111;
font-family: system-ui, sans-serif;
}
.width-demo {
width: min(100%, 680px);
display: grid;
gap: 28px;
}
.case {
padding: 20px;
border: 2px solid #111;
background: #fff;
}
.case h2 {
margin: 0 0 14px;
font-size: 20px;
}
.box {
width: 100%;
padding: 24px;
border: 8px solid #ff2f63;
background: #ffd329;
font-weight: 900;
}
.box--bad {
box-sizing: content-box;
}
.box--good {
box-sizing: border-box;
}
.long-text {
min-width: 0;
padding: 16px;
border-left: 6px solid #1f85ff;
background: #eef6ff;
overflow-wrap: anywhere;
}JS
// JavaScriptは不要です。
// 赤枠の2つを比較し、box-sizingによる幅の違いを確認してください。最短チェックリスト
- box-sizingがcontent-boxになっていないか
- width:100%へ左右padding・border・marginを追加していないか
- 100vwを使っていないか
- Flexアイテムへmin-width:0が必要ではないか
- Grid列をminmax(0,1fr)にする必要がないか
- 画像・iframe・preへmax-widthがあるか
- 長いURLへoverflow-wrap:anywhereが必要ではないか
まとめ
width:100%がはみ出す時は、要素の外幅と中身の最小幅を分けて確認します。最初にbox-sizing、次にmargin、Flex/Gridの最小幅、画像や長い文字列の順で調べると効率的です。
