
子要素が親要素(インナー幅)をはみ出すコーディングってどうやるの?
こんな疑問にお答えします。
デザインカンプによっては、下記みたいにインナー幅を超えてるレイアウトがありますよね。


初めて見たとき、どうやってコーディングするんだ?と思うはず。
でもやり方さえ知っておけば簡単に実装可能です。

すぐできるよ!
ということで、この記事では「子要素が親要素(インナー幅)をはみ出すコーディング」について解説していきます!
・【片側】子要素が親要素(インナー幅)をはみ出すコーディング
・【両側】子要素が親要素(インナー幅)をはみ出すコーディング
目次
【片側編】子要素が親要素(インナー幅)をはみ出すコーディング
まずは片側だけインナー幅をはみ出してるレイアウトからみていきましょう。display: flex;を使うときに、よくみるやつですね。

コードはこちら↓
<div class="test-box">
<div class="test-box__content">
<h3 class="test-box__title">ここにタイトルが入ります。</h3>
<p class="test-box__detail">
ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。ここにテキストが入ります。
</p>
</div>
<div class="test-box__img">
<img src="./assets/img/test01.jpg" alt="" width="853" height="562">
</div>
</div>
main {
overflow: hidden;
}
.test-box {
display: flex;
margin-bottom: 30px;
}
.test-box__content {
width: 50%;
margin-right: 30px;
}
.test-box__title {
font-size: 20px;
font-weight: 700;
margin-bottom: 20px;
}
.test-box__img {
flex: 1;
margin-right: calc(50% - 50vw);
}
- まず通常通りdisplay: flex;を使う
- margin-right: calc(50% – 50vw);を使う
- 親要素に横スクロールしないよう指定
順に見ていきましょう。
まずはいつも通りdisplay: flex;を使って、子要素を横にわけていきます。

ここまで通常。テキスト部分は「width: 50%」、画像は「flex: 1;」を指定しています。
次が一番重要。画像に対してmargin-right: calc(50% – 50vw);を使います。
.test-box__img {
flex: 1;
margin-right: calc(50% - 50vw);
}
するとこうなります↓

親要素のインナー幅を、子要素がはみ出すレイアウトにすることができました。

え?なんでこうなるの?
と、思うはず。
簡単に言うと、マイナスマージンを使用して要素の幅を伸ばしているということ。
例となる図解を用意したのでご覧ください(画面幅が2000pxで、要素の横幅が1600pxの場合)
↓


というように、画面幅の半分の長さいっぱいになるように、要素が伸びるんですよね。
最初は理解するのに、とまどうかも。。
とりあえずmargin-right: calc(50% – 50vw);を使ったら、画面半分の大きさになるというおまじないのような感じで覚えておけばよいかと。。
最後に横スクロールしないように、親要素に指定します。
というのも先ほどの画像を見ればわかるのですが、下にスクロールバーがでてるんですよね。
margin-right: calc(50% – 50vw);を使っちゃうと、横スクロールができてしまう。
そのため親要素に「overflow: hidden;」を指定しましょう。今回は例としてmainに対して指定しています。
main {
overflow: hidden;
}
ちょっとだけインナー幅をはみ出すレイアウトなら、margin-rightに入れる-50vwを数値に変えればOK。
つまり下記みたいな感じに↓
margin-right: calc(50% - 550px);
例としていれた550pxの数値を、その時のデザインによって変えれば、ちょっとだけインナー幅をはみだすレイアウトが作れますよ!
【両側編】子要素が親要素(インナー幅)をはみ出すコーディング
次に両側の子要素がインナー幅をはみ出してるレイアウトからみていきましょう。

こんな感じで、画面幅一杯に一部の子要素がはみ出してるレイアウトですね。
コードはこちら↓
<div class="test__box">
<p class="test__text">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
<p class="test__text test__text--inner">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
<p class="test__text">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
</div>
main {
overflow: hidden;
}
.test__box {
padding: 30px;
background-color: #ebebff;
margin-bottom: 50px;
}
.test__text--inner {
background: orange;
padding-right: 10px;
padding-left: 10px;
width: 100vw;
margin-left: calc(50% - 50vw);
}
- width: 100vw;を指定
- margin-left: calc(50% – 50vw);を指定
- 親要素に横スクロールしないよう指定
順に見ていきましょう。
まずはみ出したい要素にたいして、「width: 100vw;」を指定します。今回でいうと下記のオレンジ背景に対してですね。

これは画面幅一杯に表示させるようにするため。
「100vw」を使うことで、ウインドウのサイズに対して幅一杯の値を指定することができます。
で、実際に指定すると下記のようになります。

幅はウインドウサイズの値になりました。
ただ位置がずれていて、横スクロールが生まれてしまいます。
ずれた位置を真ん中に持ってくるために、 margin-left: calc(50% – 50vw);を使います。
するとこうなります↓

「画面幅一杯に表示」+「真ん中の位置」にすることができました!

どうしてこうなるの?
と、ここでも思うはず。
簡単に説明すると「親要素の半分右にずらす⇒画面幅の半分左にずらす」ということ。
まずmargin-left: 50%;を使って、親要素の半分右にずらす↓

次にmargin-left: -50vw;を使って、画面幅の半分左にずらす↓

これでインナー幅をはみ出す、画面幅一杯の子要素を、真ん中の位置で反映することができました!
とはいえ、このままだと横スクロールが発生してしまいます。
そのため親要素に「overflow: hidden;」を指定しましょう。今回は例としてmainに対して指定しています。
main {
overflow: hidden;
}
ちなみに中のコンテンツだけ、インナー幅に収める方法があります。
こんな感じで↓

中の文章だけ、他の子要素とおなじインナー幅に収まってますよね。
コードがこちら↓
<div class="test__box">
<p class="test__text">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
<p class="test__text test__text--inner">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
<p class="test__text">テキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストですテキストです</p>
</div>
.test__text--inner {
background: orange;
width: 100vw;
margin-left: calc(50% - 50vw);
padding-left: calc(50vw - 50%);
padding-right: calc(50vw - 50%);
}
やり方としては簡単。
それは「padding-left: calc(50vw – 50%);」「padding-right: calc(50vw – 50%);」を使うこと。
marginとは逆の指定をすることで、「画面幅の半分ずらす⇒親要素の半分ずらす」という表示ができます。
これで他の子要素とおなじインナー幅に収めること可能に!
まずpadding-left: 50vw;をするとこうなります↓

次にpadding-left: -50%をするとこうなります↓

ようは「画面幅の半分ずらす⇒親要素の半分ずらす」ということ。marginの逆ですよね。
これをleftだけでなく、rightにも行えばOK。
【簡単】子要素が親要素(インナー幅)をはみ出すコーディング【CSS】:まとめ
- 【片側】⇒margin-right: calc(50% – 50vw);を使う
- 【両面】⇒width: 100vw; margin-left: calc(50% – 50vw);を使う
- 中の要素だけインナー幅に収めたいなら「padding-left: calc(50vw – 50%);」「padding-right: calc(50vw – 50%);」を使う
- 親要素に「overflow: hidden;」の指定を忘れずに

子要素がインナー幅をはみだすデザインカンプはよくあるので、覚えておこう!