ikuma-t.

登壇 登壇 検索

CSSで親のコンテナのサイズをはみ出す子要素を作る

コンテナから要素をはみ出したい

このブログでは全体のレイアウトを定義した上で、その中にヘッダーやフッター、メインコンテンツを配置しています。

イメージとしては次のようなHTML構造です。

<div class="container">
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>

.containerに対してはmax-widthを設定して、コンテンツが画面幅いっぱいに広がらないようにしています。

.container {
max-width: 1200px;
margin: 0 auto;
}

これによって共通の幅を確保できるのはいいのですが、たとえばヘッダーは横幅いっぱいに広げたい場合どうすればいいでしょうか?

解決策の1つはスタイルを共通ではなく、各セクションごとに定義することです。

<div>
<header class="full-width">...</header>
<main class="container">...</main>
<footer class="container">...</footer>
</div>

これでもよいのですが、そのほかのスタイルをTailwind CSSで複数適用していたため、できれば共通のスタイルを使いたいところです。

calcでネガティブマージンを利用してはみ出す

はみ出したい子要素に対して、以下のスタイルを適用することで、やりたいことを実現できます。

body {
container-type: inline-size;
}
/* ヘッダーをはみださせる */
header {
width: 100vw;
margin-inline: calc(50% - 50cqi);
/* 親の幅に要素を寄せたい場合 */
/* padding-inline: calc(50cqi - 50%); */
}
/* 変更なし */
.container {
max-width: 1200px;
margin: 0 auto;
}

HTMLについては、次のようになります。

<div class="container">
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>

適用のイメージについて、個人的には次のように考えるとわかりやすいかと思います。

  1. 親要素を基準に、100vwで要素を横幅いっぱいに広がる。親基準なので、画面の端からではなく親の端から広がる。これを調整したい。
  2. 親要素の左右それぞれに対して(つまり半分ずつに分割して考える)、画面幅の要素から親要素を引いた値をうめたい。これをネガティブマージンで再現する。
  3. margin-inlineを利用して、水平方向に対して、2のマージンを適用する。

細かいポイントがコンテナクエリを使っていることです。50vwだと、スクロールバーを含めた部分までで横幅を計算するので、横スクロールバーが生じてしまいます。

bodyに対しての純粋な半分が欲しいので、bodyをコンテナに指定した上で、その半分である50cqiを指定すればこの問題も解決です(cqiはコンテナーのインライン(横書きだと水平方向)の1%をさす単位です)。

参考

ikuma-t

ikuma-t

about

9割笑顔、1割 (´・ω・)