CSSで子要素の幅を親要素より大きくしてはみ出させよう!

タイトル画像のようなものです。海外もののクールなデザインのブログテーマで結構見かけますね。

この記事はスマホサイズでは調整しておりません。

その1: marginとwidthで指定する

左右に50pxずつはみ出して配置する

親要素をdiv.parent01、子要素をdiv.child-test01とします。
ここでは子要素を親要素より左右に50pxずつはみ出させてみます。

<div class="parent01">
  親要素ここから
  <div class="child-test01">子要素</div>
  親要素ここまで
</div>

HTMLはclassの違いはありますが、基本的にこの形です。

この投稿記事内でデモもやるため、実際にはpタグが無駄に混じっていますがお見逃しください。WordPressでpタグを自動挿入させないテクもあるようですが。。

div.parent01 {
  background: #FAFAE1;
}
div.child-test01 {
  width: calc(100% + 100px);
  margin: 0 -50px;
  background: #EECE34;
}

子要素の幅をwidth: 100%;にすると、親要素の幅に準拠します。そのため、はみ出させてたい幅をcalcで足してあげます。
また、marginの左右をその分マイナスの値に設定することで子要素が中央に位置します。

Demo
親要素ここから

子要素

親要素ここまで

左にだけ50pxずつはみ出して配置する

親要素div.parent01はママ、子要素をdiv.child-test02とします。
margin-rightを0にしました。

div.child-test02 {
  width: calc(100% + 50px);
  margin: 0 0 0 -50px;
  background: #EECE34;
}
Demo
親要素ここから

子要素

親要素ここまで

画面幅いっぱいにはみ出して配置する

親要素div.parent01はママ、子要素をdiv.child-test03とします。
子要素にwidth: 100vw;を指定します。このvw、vhはブラウザのスクロールバーの分まで含むサイズとなります。

左右のmarginは、画面幅100vwの半分をマイナスにしそれに親要素の幅100%の半分を加えた数値を設定します。
calc(-100vw / 2 + 100% / 2)となりますが、平たくcalc(50% - 50vw)とします。

div.child-test03 {
  width: 100vw;
  margin: 0 calc(50% - 50vw);
  background: #EECE34;
}
Demo
親要素ここから

子要素

親要素ここまで

スクロールバー分に幅も含んでいるためか、想定よりはみ出してしまいました。。(このブログはbodyにoverflow-x: hidden;を指定しているため、横スクロールバーは出現しません)
background-imageやpaddingを余裕持って指定すればOKかな……?

その2: positionで指定する

位置調整と言えばposition!

左右に50pxずつはみ出して配置する

親要素をdiv.parent02、子要素をdiv.child-test04とします。
親要素を基準としたいのでposition: relative;を、子要素を位置調整したいのでposition: absolute;を指定し、子要素のleft、rightにはみ出させたい数値をマイナスで指定します。

div.parent02 {
  position: relative;
  background: #FAFAE1;
}
div.child-test04 {
  position: absolute;
  left: -50px;
  right: -50px;
  margin: auto;
  background: #EECE34;
}
Demo
親要素ここから

子要素

親要素ここまで

ここではあえて子要素にtop、bottomの位置指定はしていません。子要素にposition: absolute;を指定しているため親要素を位置の基準として上に浮いています。場合によってはもう一個divを入れ子にしてそちらを親要素とした方がいいかもしれません。

左にだけ50pxずつはみ出して配置する

親要素div.parent02はママ、子要素をdiv.child-test05とします。
これは素直に子要素のrightを0にします。

div.child-test05 {
  position: absolute;
  left: -50px;
  right: 0;
  margin: auto;
  background: #EECE34;
}
Demo
親要素ここから

子要素

親要素ここまで

画面幅いっぱいにはみ出して配置する

親要素div.parent02はママ、子要素をdiv.child-test06とします。
(この例ではposition:relative;をかけている親要素はブラウザの中央にある前提です。)
画面幅いっぱいなのでwidth: 100vw;を指定します。leftとrightの数値ですが正直-100%である必要はないのですが、同じ数値を指定してください。

div.child-test06 {
  position: absolute;
  left: -100%;
  right: -100%;
  width: 100vw;
  margin: auto;
  background: #EECE34;
}
Demo
親要素ここから

子要素

親要素ここまで

前章marginとwidthで指定したときと同様、スクロールバー分も含んでいるため子要素は親要素どころかブラウザ幅よりはみ出してしまっていますね。

その3: WordPress、Gutenbergのビジュアルエディターなら

開発側はあまりGutenbergのビジュアルエディターを使っていないかもしれません。しかしHTMLの知識が無いクライアントにとってはサクサク投稿ができて良いかもしれません(ケースバイケースですね。各社、ここら辺どう対応されてるんでしょう?)

そのGutenbergのビジュアルエディターの投稿画面で、子要素が親要素よりはみ出させる処理をすることができるようにするために、functions.phpとCSSを編集します。
TwentyTwentyというWordPressにデフォルトで入っているテーマを使用している場合は、すでにテーマCSSに記述されているためCSSの編集は特に必要ありません。

function gutenberg_support_setup() {
  add_theme_support( 'wp-block-styles' );
  add_theme_support( 'align-wide' );
}
add_action( 'after_setup_theme', 'gutenberg_support_setup' );
.alignwide {
  width: calc(100% + 100px);
  max-width: none;
  margin: 0 -50px;
}
.alignfull {
  width: 100vw;
  max-width: none;
  margin: 0 calc(50% - 50vw);
}

CSSでの.alignwide.alignfullの記述については諸説ありますが、お使いのテーマ、デザインで良いようになるよう調整しましょう。
ここでは前述の「その1: marginとwidthで指定する」で使用していたCSSを流用します。

このブログの親テーマunderstrtapではfiguremax-width:100%;が指定されていたので、それを打ち消すためにmax-width: none;を追記しています。これはテーマによりますね。

参考: TwentyTwentyのテーマCSS

TwentyTwentyでは結構細かく設定してあります。参考までに。

Demo

Gutenbergで画像を配置してから「配置 > 幅広」に設定しました(下図参照)。幅広が.alignwideのことですね。実際にはfigure.alignwideが設定されることになります。 本文のコンテンツ幅より左右にはみ出しています。

Gutenbergの投稿画面
Demo

こちらは「配置 > 全幅」.alignfullを当ててみました。

便利ですが、クライアントの自由な使い方に対応するCSSを記述するの、想像力が試されますね。

Demo

Google MapはカスタムHTMLで埋め込む感じですね。手動でclass="alignwide"を付け加えました。
野付半島はいいぞ!

おまけ

WordPressのGutenbergビジュアルエディター、開発側は脳内変換できますが、クライアントは投稿・編集画面と実際のサイトのデザインが異なると戸惑うじゃないですか。
投稿・編集画面をサイトのデザインに合わせる技があるようです。