CSS 子要素を親要素よりはみ出して全体表示にするには
CSSで子要素を親要素よりはみ出して全体表示させる方法
今回は現場でまぁまぁ使われるCSSテクニックの1つを紹介するぞ。
最終的なレイアウトサンプル
まずは最終的な完成形を見せるぞ。こんなイメージだ
See the Pen
by 魔王 (@maou_frontend)
on CodePen.
子要素をはみ出させるHTMLとCSS
HTMLの内容
<div class="container">
<p>祖父要素内のコンテンツ</p>
<div class="content">
<p>親要素内に収まるコンテンツ</p>
<p>親要素内に収まるコンテンツ</p>
<p>親要素内に収まるコンテンツ</p>
<div class="ContentOver-box">
<div class="ContentOver-box-inner">
親要素を超えて表示したい子要素コンテンツ
</div>
</div>
<p>親要素内に収まるコンテンツ</p>
<p>親要素内に収まるコンテンツ</p>
</div>
</div>
CSSの内容
.container{
padding: 0 20px;
background-color:#ffe3e3;
position: relative;
overflow: hidden;
}
.content{
max-width:500px;
margin:auto;
padding:20px ;
background-color:#fff;
}
.ContentOver-box{
padding: 2rem 0;
margin: 0 calc(50% - 50vw);
width: 100vw;
background: #ddd;
}
.ContentOver-box-inner{
margin: 0 15px;
padding: 25px;
background-color: #fff;
}
実装するときに注意するポイントは4つだ!
子要素に「margin: 0 calc(50% - 50vw);」と「width: 100vw;」を指定する
子要素が親要素をはみ出させるには、子要素にcssで「margin: 0 calc(50% - 50vw);」と「width: 100vw;」を指定すれば良い。まずはそれだけで親要素をはみ出して表示されるであろう。
100vwの範囲はスクロールバーも含む
横幅をvwで指定すると縦スクロールバーを含んだ長さになるので、縦スクロールバーが表示させるかどうかで、横幅の長さが変わってしまうのだ。
これは本当に注意せよ。なにせ横幅はきっちり指定しているつもりでも、コンテンツの高さやブラウザの大きさでコンテンツ幅がずれてしまう。
横幅を設定しているはずなのに、コンテンツの高さが横幅に影響してくるというおかしな話になる。
さらに、スクロールバーはmacのブラウザだと表示されていないが、windowsだとスクロールバーが常時表示されているので、macで制作して大丈夫だと思っていてもクライアントのwindowsでは表示が乱れてしまったりするのだ。
注意していないと、まさにメダパニを受けたような状態に陥るぞ。
横スクロールバーを表示させないために祖父要素が必要になる。
上で伝えた縦スクロール問題を解決するため、子要素が親要素をはみ出すCSSテクニックには実際には親要素だけでなく、その上に祖父要素も設置する必要がある。
ちなみに下に祖父要素を使わないバージョンを用意した。
See the Pen
親要素を超えて子要素を表示する(失敗例) by 魔王 (@maou_frontend)
on CodePen.
windowsで見てみると下に横スクロールが表示されているだろう?
windowsで見ているものは更にcodepenに入って、コンテンツ幅を動かしてみるがいい。縦スクロールが表示された瞬間、横スクロールも表示されることが感覚的にわかるぞ。
ん?しかたがない、macで見ているもののために画像も用意してやろう。
これがwindowsの状態だ。下にスクロールバーが表示されてしまっている。
codepenでコンテンツを広く(すべて)表示させると、横スクロールバーが消える
コンテンツを狭く(一部)表示させると、横スクロールも出てくる。vwが縦スクロールバーまでの幅を計算しているので、縦スクロールバーが無い状態で計算した幅と当然異なり、余った分が横スクロールを表示させることになってしまう。
祖父要素に「position: relative;」 と「 overflow: hidden;」を指定する
このスクロールバー問題はvwの性質上どうしても起こるので、起きないようにするのではなく、起きた後に消す処理を入れる。
それが祖父要素に「position: relative;」 と「 overflow: hidden;」を指定することなのだ。
よく似たような記事で
スクロールバーを消したいなら「position: relative;」 と「 overflow: hidden;」を指定すれば大丈夫☆
と書いてあるが、正確には「祖父要素」に「position: relative;」 と「 overflow: hidden;」を指定しなければ意味がない。親要素に「position: relative;」 と「 overflow: hidden;」を指定してもせっかくはみ出した子要素が消えるだけだ。
嘘だと思うなら上の祖父要素がないcodepenの親要素であるcontentに
position: relative;
overflow: hidden;
を追加してみるが良い。
どんな時に使うのか
ブログやHPを作成する際、ほとんどの場合コンテンツ表示幅を設定するはずだ。通常すべてのコンテンツはその幅の中に収まるようにできている。今回のテクニックはそのルールの例外を作ることになる。
この親要素をはみ出させるテクニックはトップページやLPでよく使われるな。他にはコンテンツの区切りとして使われることもあるぞ。
例えば下の画像のように、途中に画像背景のエリアを差し込んだりするデザインに使える。
どちらかというと、海外のコーポレートサイトでよく見るデザインかもしれぬ。
Uberのサイトではリンクエリアの背景をグレーにすることで、リンクを強調しておる。
最初から外枠いっぱいに表示させることを考えて制作するのもあり。
今回は親要素を突き抜けて子要素を横幅いっぱいに表示させる方法になるが、そもそも最初から横幅いっぱいに表示するデザインであれば、下の例のように親要素で横幅を指定せずにセクションごとに横幅を設定していけばよいだろう。
まぁ・・このやり方はページを新規に作る場合に限ると思うがな。すでに出来上がってるページで外枠いっぱいに表示させるなら今回紹介している方法を使うべきであろう。
なぜならcontentやcontainerといったclassやidはサイトデザインの根幹部分に関わっているので、出来上がってるサイトでこれらのcssルールを改修すると、他のページにも影響を及ぼしてしまう恐れがあるのだ。
<section class="nomal-width">普通の広さのコンテンツ</section>
<section class="nomal-width">普通の広さのコンテンツ</section>
<section class="full-width">横幅いっぱいのコンテンツ</section>
<section class="nomal-width">普通の広さのコンテンツ</section>
CSSで子要素を親要素よりはみ出して全体表示させる方法まとめ
- 子要素に「margin: 0 calc(50% - 50vw);」と「width: 100vw;」を指定する
- 祖父要素に「position: relative;」 と「 overflow: hidden;」を指定する。
- 最初から外枠いっぱいに表示させることを考えて制作するのもあり。
ところで・・・祖父要素っていうのか?書いてて初めて見た気がするぞ。
まぁよい!以上がCSSで子要素を親要素よりはみ出して全体表示させる方法だ!