誰もがぶつかる、「width:100%なのに広がらない問題」
CSSを書き始めてすぐにぶつかる壁があります。「width:100% を指定したのに、なぜか要素が画面幅いっぱいに広がらない」という現象です。
「100%って全体じゃないの?」と思うのは当然ですが、CSSにおける 100% は「画面の100%」ではなく、「親要素の幅の100%」 を意味します。
この一点を理解するだけで、多くの混乱が解消されます。
本記事では、width:100% が意図通りに動かないケースを8つに分類し、それぞれの原因・解決策を具体的なコード例で徹底解説します。
前提知識:width:100% の「100%」は何に対する割合か
まず最初に、CSSにおけるパーセンテージの基本ルールを押さえておきましょう。
子要素の width:100% = 親要素の幅
つまり、親要素の幅が決まっていなければ、子要素は 100% を計算できません。
<div class="parent">
<div class="child">このdivにwidth:100%を指定</div>
</div>
.parent {
width: 500px; /* 親の幅が決まっている */
}
.child {
width: 100%; /* → 500px になる */
}
親の幅が決まっていなかったりinline要素である場合、width:100% は期待通りに機能しないことがあります。
原因1:親要素の幅が決まっていない
最も多い原因がこれです。
発生ケース
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
<span class="parent">
<div class="child">広がらない</div>
</span>
.child {
width: 100%;
}
<span> はインライン要素であり、コンテンツの幅に合わせて縮むため、子要素の width:100% は「インライン要素の縮んだ幅の100%」になってしまいます。
解決策
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.parent {
display: block; /* または display: flex; display: grid; */
width: 100%; /* または明示的な幅を指定 */
}
チェックリスト
- 親要素が
display: inlineになっていないか - 親要素に明示的な幅が指定されているか、またはブロック要素として自然に広がれるか
原因2:box-sizing による幅のはみ出し
「width:100% を指定したのに、横スクロールが出てしまう」という現象の多くがこれに起因します。
発生ケース
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.child {
width: 100%;
padding: 20px;
border: 1px solid #ccc;
}
CSSのデフォルト box-sizing: content-box では、width はコンテンツ領域のみを指します。padding や border はその外側に加算されます。
実際の表示幅 = width(100%) + padding左右(40px) + border左右(2px)
つまり上記のようなCSSを書いている場合、親要素の幅を超えてはみ出してしまいます。
はみ出した分、スクロールバーが表示されるわけですね。
解決策
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
* {
box-sizing: border-box;
}
border-box にすると、width の中に padding と border が含まれるようになります。現代のCSSリセットではこれをグローバルに設定するのが一般的です。
/* よく使われるリセット */
*, *::before, *::after {
box-sizing: border-box;
}
原因3:margin は width:100% の外側に加算される
box-sizing: border-box を設定しても、margin だけは例外です。
発生ケース
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.child {
box-sizing: border-box;
width: 100%;
margin: 0 24px; /* これが問題 */
}
margin は width の計算に含まれないため、左右に 24px ずつ追加されて親要素からはみ出します。
解決策
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
margin の代わりに padding を親要素側に持たせるか、calc() を使って計算します。
/* 親側にpaddingを持たせる */
.parent {
padding: 0 20px;
}
.child {
width: 100%;
}
/* または calc() で計算 */
.child {
width: calc(100% - 48px); /* 左右のmargin分をマイナスする */
margin: 0 24px;
}
原因4:Flexbox・Grid の子要素は挙動が変わる
FlexboxやGrid コンテナの中では、width:100% の意味が少し変わります。
Flexbox の場合
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.parent {
display: flex;
}
.child {
width: 100%; /* flexアイテムとして解釈される */
}
Flexbox では、子要素(flex アイテム)のサイズは flex-basis、flex-grow、flex-shrink によって制御されます。width:100% を指定しても、flex アイテムとしての制約が優先されることがあります。
/* 確実に広げたい場合 */
.child {
flex: 1; /* flex-grow: 1 の省略形 */
/* または */
flex-basis: 100%;
flex-shrink: 0;
}
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
Grid の場合
.parent {
display: grid;
grid-template-columns: 200px 1fr;
}
.child {
width: 100%; /* グリッドセルの幅の100% */
}
Grid では子要素はグリッドセルの中に配置されます。width:100% はセルの幅に対する割合になります。セルをまたいで広げたい場合は grid-column を使います。
.child {
grid-column: 1 / -1; /* 全列にまたがる */
}
原因5:position: absolute または position: fixed の要素
position: absolute や position: fixed を指定した要素は、通常のドキュメントフローから外れます。この状態での width:100% は「位置の基準となる祖先要素(包含ブロック)の幅の100%」を指します。
発生ケース
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.parent {
position: relative; /* 親にしたい要素にrelativeを指定する */
width: 500px;
}
.child {
position: absolute;
width: 100%; /* → 500px(.parentの幅) */
}
親要素にposition:relative;を付けることで、子要素がabsoluteのときは親基準で配置されます。
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
position: fixed の場合は、包含ブロックがビューポート(画面)になります。
.child {
position: fixed;
width: 100%; /* → 画面幅の100% */
}
原因6:display: inline または display: inline-block の要素
ブロック要素と異なり、インライン系の要素は width プロパティの効きが異なります。
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
インライン要素(display: inline)
<span>、<a>、<em> などのインライン要素は、width を指定しても完全に無視されます。
span {
width: 100%; /* 無効 */
}
インラインブロック要素(display: inline-block)
width: 100% は効きますが、親要素の幅に収まらない場合があります。
.child {
display: inline-block;
width: 100%;
/* inline-block は匿名インラインボックスを生成するため、
隣接するテキストノードや空白の影響を受けることがあります */
}
解決策
意図的に幅いっぱいに広げたい要素には display: block を使うのが最も確実です。
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.child {
display: block;
width: 100%;
}
原因7:min-content / max-content の影響
FlexboxやGridの文脈では、要素の最小幅(min-content)が width:100% より優先されることがあります。
発生ケース
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.parent {
display: flex;
width: 300px;
}
.child {
width: 100%;
/* 中のテキストが長い場合、min-content が 300px を超えることがある */
}
Flexbox の仕様では、flex アイテムはデフォルトで min-width: auto を持っており、これが内容物の最小幅(テキストが折り返さない最短幅)に相当します。
解決策
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.child {
width: 100%;
min-width: 0; /* min-width: auto を上書きする */
overflow: hidden; /* または overflow-wrap: break-word */
}
原因8:親要素に overflow: hidden や max-width がある
親要素が表示領域を制限している場合、子要素の width:100% はその制限された幅に従います。
max-width の例
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.parent {
max-width: 800px;
margin: 0 auto; /* センタリング */
}
.child {
width: 100%; /* → 最大800px */
}
これ自体は正常な挙動ですが、「画面いっぱいに広げたい」なら vw を使う必要があります。
See the Pen Untitled by STELLAR INTER (@STELLAR-INTER) on CodePen.
.child {
width: 100vw; /* ビューポート幅の100% */
margin-left: calc(-50vw + 50%); /* 親のセンタリングを打ち消す */
}
ただし、vwは親要素基準での幅ではなく、デバイスの幅基準となります。
親要素が100pxであったとしても、子要素に100vwを指定すればデバイス幅いっぱいに広がり、親からはみ出します。
一覧表:原因と解決策のまとめ
| 原因 | 症状 | 解決策 |
|---|---|---|
| 親の幅が未定義 | 子が縮む | 親に display: block と幅(px)を指定 |
box-sizing: content-box |
padding/border ではみ出す |
box-sizing: border-box をグローバル設定 |
margin の加算 |
margin分だけはみ出す | 親に padding を移す or calc() を使う |
| Flexbox/Grid の制約 | flex アイテムが縮む |
flex: 1 や min-width: 0 を使う |
position: absolute/fixed |
包含ブロックが意図と異なる | 包含ブロックになる祖先に position: relative を設定 |
display: inline |
width が無効 |
display: block に変更 |
min-content の制約 |
内容が縮まない |
min-width: 0 を追加 |
親の max-width
|
画面幅に届かない |
100vw + ネガティブマージンを使う |
まとめ
width:100% が広がらない原因は、ほぼすべて「100% の基準となる親要素(包含ブロック)の幅が、想定と異なっている」ことに集約されます。
ポイントをおさらいすると、
-
width:100%は常に「親要素のコンテンツ幅」に対するパーセンテージ -
paddingとborderを幅に含めたければbox-sizing: border-boxを使う -
marginはどんな設定でも幅の外側に加算される - Flexbox・Grid の中では追加の制約が働くことがある
-
position: absolute/fixedの包含ブロックは通常フローと異なる
CSSの幅計算はルールさえ覚えてしまえば、ほぼすべての挙動を予測できるようになります。開発者ツールを活用しながら、一つずつ原因を潰していくのが確実な解決への近道です。