これは覚えておきたい! モダンCSSで実装する、記事は中央に画像は幅いっぱいにフルブリードレイアウトを実装するテクニック
Post on:2025年2月13日
フルブリードレイアウトとは最近のWebサイトのUIでもよく見かける、記事は中央配置に、画像や動画などは幅いっぱいに表示されるレイアウトのことです。これまではCSS Gridなどで実装されていたと思いますが、今回紹介するのはモダンCSSで実装できるテクニック。
CSSはわずか4行ですが、モダンCSSのテクニックがたくさん詰まっており、フルブリードレイアウトはさまざまなカスタマイズにも対応しています。

Full-Bleed Layout with Modern CSS
by Temani Afif
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
how to create a Full-bleed layoutで、数行のCSSでフルブリードレイアウトを作成するテクニックを紹介しました。このようなレイアウトに馴染みのない人は、下記のデモをご覧ください。この記事ではこのテクニックについて深く掘り下げて解説しようと思います。
フルブリードレイアウト(Full-Bleed Layout)とは元々は出版用語で、用紙の端までいっぱいに広がるレイアウトのことです。Webサイトでは記事は最大幅を設定して中央配置にし、画像などはページ幅いっぱいに配置します。

フルブリードレイアウト
実際の動作は、デモページでご覧ください。
※右上「Edit on CodePen」をクリックして、スクリーンサイズを広げて見た方がよいと思います。
See the Pen
Full-bleed layout with modern CSS by coliss (@coliss)
on CodePen.
CSS Gridによるフルブリードレイアウトについて知りたい人は下記をどうぞ。

シンプルなCSSで実装できる! 記事は中央に固定幅、画像は幅いっぱいに、フルブリードレイアウトを実装するテクニック
ここで紹介するCSSのテクニックは、上記よりかなり進化しています。
フルブリードレイアウトを実装するCSS
メインのコンテンツエリアは一定の幅に制限されて中央配置され、いくつかの要素はページ幅いっぱいに配置されます。このようなレイアウトを実装するテクニックはいくつかありますが、私が考案したものはモダンCSSでわずか4行のコードで実装できます。
1 2 3 4 5 6 7 8 9 10 |
html { container-type: inline-size; } main { --_m: max(1em, 50cqw - 400px/2); margin-inline: var(--_m); } .full-bleed { margin-inline: calc(-1 * var(--_m)); } |
ぱっと見、このCSSは何をしているのか分からない、と思うかもしれません。しかし、下記の解説を読むと、その考えが変わると思います。この背後にあるロジックを理解し、この状況を処理する効率的な方法であることが分かります。
html要素をコンテナにする理由
vw
などのビューポート単位は知っていると思います。100vw
はブラウザウインドウの幅、つまりビューポートを意味します。このようなメトリックに頼るのはよくあることですが、これには欠点があります。100vw
はスクロールの幅があるかどうかに関係なく、常に同じ結果になります。これは少しイライラさせるもので、望ましくないオーバーフローが発生することもあります。
この問題を説明するために、簡単なデモを用意しました。
See the Pen
Scrollbar issue with 100vw by coliss (@coliss)
on CodePen.
コンテナの高さは500px
です。ページがコンテナ全体を表示するのに十分な高さがある場合はうまくいきますが、高さが足りない場合は水平スクロールバーが表示されます。
理想は100vw
の振る舞いを変更してほしいのですが、それはできません。dvw
単位の登場はこの問題を解決する機会になると思われますが、そうではありません。
参考: CSSの新しい単位「lvh」「svh」これでiOSのSafariで100vhがビューポートの高さではない仕様に対応できる
html
要素をコンテナにする理由は、100cqw
を使用して(ページ全体ではなく)html
の幅を照会する機能を解放するためです。html
要素はページの最上位の要素であり、ブロックレベル要素であるため、スクロールバーを考慮しながら常にページの幅になります。言い換えると、100cqw
はページにスクロールバーが表示されるとその分小さくなります、これは完璧な動作です!
下記のデモは、上記を100vw
の代わりに100cqw
を使用したものです。高さが足りなくても水平スクロールバーは表示されません!
See the Pen
Fixing scrollbar issue using 100cqw by coliss (@coliss)
on CodePen.
多くのテクニックのように100vw
に頼るのではなく、少しだけ優れた100cqw
を使用します。そして、そのためにはhtml
要素をコンテナにする必要があります。


margin-inlineで何をしていますか?
水平方向の中央に配置された最大幅のコンテナが必要だとしたら、あなたは直感的に下記のようなCSSを書くでしょう。
1 2 3 4 |
main { max-width: 400px; margin-inline: auto; /* もしくは: margin: 0 auto; */ } |
このCSSはかなりシンプルで効率的で、CSSの基本的な経験がある人なら簡単に理解できるでしょう。この方法を続けることをお勧めしますが、max-width + centeringで使用したmargin
だけを使用して上記の2行のCSSと同じことができます。

1行のCSSで最大幅と中央揃えを実装
コンテナの最大幅をw
にする必要がある場合、両側の残りのスペースは50% - w/2
に等しくなります。このスペースを使用してマージンを定義すれば、望みのものができます。
直感には反するかもしれませんが、論理的です。幅を定義してブラウザにマージンを計算させる(auto
を使用)か、逆にマージンを定義してブラウザに計算させるかの違いです。margin
とは異なり、width
のデフォルト値はすでにauto
なので、margin
定義するだけで十分です。
1 2 3 |
main { margin-inline: max(0px, 50% - 600px/2); } |
max()
を使用しているのは、小さなスクリーンで負の値が出ないようにするためです。つまり、値を0
に固定しています。
margin
がいくつかのポイントで100px
に等しいとします。コンテナ内の要素のマージンが反対(つまり、-100px
)に等しい場合、以前のマージンは打ち消され、コンテナの幅いっぱいに広がります。
See the Pen
Negate margin by coliss (@coliss)
on CodePen.
margin-inline
で何をしているのかお分かりいただけでしょうか。max-width
を設定し、メインコンテナを中央に配置するために使用される同じマージンがフルブリード要素にも使用され(負の符号付きで)、コンテナの外側にブリードしてスクリーンの端まで拡張されます。
1 2 3 4 5 6 7 |
main { --_m: max(0px, 50% - 600px/2); margin-inline: var(--_m); } .full-bleed { margin-inline: calc(-1 * var(--_m)); } |
マージンはカスタムプロパティで定義され、main
と.full-bleed
で負符号付きで2回使用されます。ただし、見た目は完璧ですが、上記のコードだけでは動作しません。
また、単位に%
を使用しているので、計算の参照元が両方の要素で同じではないため、両方のマージンが等しくなることはありません。解決策はお分かりだと思いますが、参照元が常に同じ(スクロールバーを考慮したページの幅)になるように、前述で解説したcqw
単位を使用します。
これでパズルは完成です!
シンプルなCSSによるフルブリードレイアウトができます。
1 2 3 4 5 6 7 8 9 10 |
html { container-type: inline-size; } main { --_m: max(0px, 50cqw - 600px/2); margin-inline: var(--_m); } .full-bleed { margin-inline: calc(-1 * var(--_m)); } |
さらに、max()
関数内の0px
を任意の値に変更すれば、それが最小マージンとして機能します。つまり、メインコンテナが小さなスクリーンで持つマージンです。
CSSの別の書き方
仕組みが分かったところで、CSSをもう少し読みやすくしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
html { container-type: inline-size; } main { --w: 600px; /* the max-width */ --m: 1em; /* margin on small screen */ margin-inline: max( var(--m),50cqw - var(--w)/2); } .full-bleed { margin-inline: min(-1*var(--m),var(--w)/2 - 50cqw); /* same as margin-inline: calc(-1*max(var(--m),50cqw - var(--w)/2)) */ } |
このCSSだと、2つのカスタムプロパティ値を設定するだけなので、少しだけ優れています。このCSSを使用すればフルブリード要素のマージン動作を更新できるバリエーションを増やすこともできます。
たとえば、-1*var(--m)
を0px
に置き換えると、下記のようになります。
1 2 3 |
.full-bleed { margin-inline: min(0px, var(--w)/2 - 50cqw); } |
小さなスクリーンでは、要素のマージンは-m
に等しくなります。言い換えると、小さなスクリーンでは要素はブリードアウトの動作を失います。
フルブリードのバリエーションを4つ(デフォルトを含む)思いつきました。
1 2 3 4 5 6 7 8 9 10 11 12 |
.full-bleed-1 { margin-inline: min(-1*var(--m),var(--w)/2 - 50cqw); } .full-bleed-2 { margin-inline: min(-1*var(--m),var(--w)/2 - 50cqw + var(--m)); } .full-bleed-3 { margin-inline: min( 0px,var(--w)/2 - 50cqw); } .full-bleed-4 { margin-inline: min( 0px,var(--w)/2 - 50cqw + var(--m)); } |
それぞれの挙動が分かるデモを用意しました。各バリエーションを理解するために、フルスクリーンにしてサイズを変更して見てみてください。
See the Pen
Full-bleed layout variations by coliss (@coliss)
on CodePen.
全幅のコンテンツを同じ幅に制限する
最後に、背景色だけが幅いっぱいに広がるテクニックを解説します。コンテンツは他の部分と同じ最大幅に制限されており、背景だけが幅いっぱいに表示されます。これはフルブリードレイアウトの特殊なケースで、マージンなどの複雑な計算をする必要はありません。
1 2 3 4 |
.full-background { border-image: conic-gradient(pink 0 0) fill 0//0 100vw; padding-block: 10px; } |
実際の動作は、デモページでご覧ください。
See the Pen
Full screen background color by coliss (@coliss)
on CodePen.
このCSSの仕組みは、border-image
のoutset
機能を使用して、左右に溢れるように背景色を表示しています。border-image
プロパティは理解するのがすこし難しいですが、Awesome CSS border-image Propertyという詳細な解説があります。
終わりに
短いCSSでフルブリードレイアウトを作成するだけでなく、要素のマージン動作をコントロールすることも簡単に調整できます。他のバリエーションを思いつきますか? 数式を微調整して、他の便利で面白い挙動を実現できると確信しています。もし、何か面白いアイデアがあれば、ぜひお知らせください!
sponsors