2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「width:100%」なのに広がらない原因を完全に理解する

2
Posted at

誰もがぶつかる、「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 はコンテンツ領域のみを指します。paddingborder はその外側に加算されます。

実際の表示幅 = 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 の中に paddingborder が含まれるようになります。現代のCSSリセットではこれをグローバルに設定するのが一般的です。

/* よく使われるリセット */
*, *::before, *::after {
  box-sizing: border-box;
}

原因3:marginwidth: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; /* これが問題 */
}

marginwidth の計算に含まれないため、左右に 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-basisflex-growflex-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: absoluteposition: 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: hiddenmax-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: 1min-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% は常に「親要素のコンテンツ幅」に対するパーセンテージ
  • paddingborder を幅に含めたければ box-sizing: border-box を使う
  • margin はどんな設定でも幅の外側に加算される
  • Flexbox・Grid の中では追加の制約が働くことがある
  • position: absolute/fixed の包含ブロックは通常フローと異なる

CSSの幅計算はルールさえ覚えてしまえば、ほぼすべての挙動を予測できるようになります。開発者ツールを活用しながら、一つずつ原因を潰していくのが確実な解決への近道です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?