30 CSS Grid Layouts01 / 30
Full-Bleed Layout
The layout every long-form article needs: body text locked to a readable 65ch measure, while images and pull-quotes break out to the full viewport width — no negative margins, no calc() hacks, no wrapper divs. One named-line grid does all of it, and any child can opt into full bleed with a single class.
Published
The code
<section class="cgl-01" aria-label="Full-bleed layout demo">
<article class="cgl-01__article">
<header class="cgl-01__head">
<p class="cgl-01__kicker">Layout Pattern № 01</p>
<h2>The measure stays put. The imagery doesn't.</h2>
</header>
<p>Body copy locks to a comfortable 65-character measure, centred by two elastic gutter tracks. Resize the page — the text column holds while the gutters breathe.</p>
<figure class="cgl-01__media cgl-01__media--bleed">
<div class="cgl-01__ph" role="img" aria-label="Full-width placeholder image"></div>
<figcaption>This figure spans grid-column: full — edge to edge, no negative margins.</figcaption>
</figure>
<p>Back in the content column, as if nothing happened. Any element can opt out with one class; everything else flows normally.</p>
<blockquote class="cgl-01__quote cgl-01__quote--bleed"><p>"Full bleed is a grid decision, not a margin hack."</p></blockquote>
</article>
</section><section class="cgl-01" aria-label="Full-bleed layout demo">
<article class="cgl-01__article">
<header class="cgl-01__head">
<p class="cgl-01__kicker">Layout Pattern № 01</p>
<h2>The measure stays put. The imagery doesn't.</h2>
</header>
<p>Body copy locks to a comfortable 65-character measure, centred by two elastic gutter tracks. Resize the page — the text column holds while the gutters breathe.</p>
<figure class="cgl-01__media cgl-01__media--bleed">
<div class="cgl-01__ph" role="img" aria-label="Full-width placeholder image"></div>
<figcaption>This figure spans grid-column: full — edge to edge, no negative margins.</figcaption>
</figure>
<p>Back in the content column, as if nothing happened. Any element can opt out with one class; everything else flows normally.</p>
<blockquote class="cgl-01__quote cgl-01__quote--bleed"><p>"Full bleed is a grid decision, not a margin hack."</p></blockquote>
</article>
</section>.cgl-01,
.cgl-01 *,
.cgl-01 *::before,
.cgl-01 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-01 {
width: 100%;
min-height: 100vh;
--ink: oklch(0.24 0.02 60);
--paper: oklch(0.97 0.012 85);
--accent: oklch(0.55 0.14 40);
font-family: Georgia,'Times New Roman',serif;
color: var(--ink);
background: var(--paper);
}
.cgl-01 .cgl-01__article {
display: grid;
grid-template-columns: [full-start] minmax(1.5rem,1fr) [content-start] min(65ch,100% - 3rem) [content-end] minmax(1.5rem,1fr) [full-end];
row-gap: 1.4rem;
padding-block: 3rem;
}
.cgl-01 .cgl-01__article>* {
grid-column: content;
}
.cgl-01 .cgl-01__media--bleed,
.cgl-01 .cgl-01__quote--bleed {
grid-column: full;
}
.cgl-01 .cgl-01__kicker {
font-family: system-ui,sans-serif;
font-size: .72rem;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--accent);
margin-block-end: .6rem;
}
.cgl-01 h2 {
font-size: clamp(1.5rem,4vw,2.2rem);
line-height: 1.15;
text-wrap: balance;
}
.cgl-01 p {
font-size: 1.02rem;
line-height: 1.65;
}
.cgl-01 .cgl-01__ph {
inline-size: 100%;
aspect-ratio: 21/7;
background: linear-gradient(115deg,oklch(0.62 0.13 40),oklch(0.48 0.1 25) 50%,oklch(0.35 0.07 50)),repeating-linear-gradient(-45deg,transparent 0 18px,oklch(1 0 0/.06) 18px 36px);
background-blend-mode: overlay,normal;
}
.cgl-01 figcaption {
font-family: system-ui,sans-serif;
font-size: .75rem;
color: color-mix(in oklab,var(--ink) 60%,var(--paper));
padding-inline: 1.5rem;
padding-block-start: .5rem;
}
.cgl-01 .cgl-01__quote--bleed {
background: var(--ink);
color: var(--paper);
padding-block: 2.2rem;
padding-inline: 1.5rem;
display: grid;
grid-template-columns: inherit;
}
.cgl-01 .cgl-01__quote--bleed p {
grid-column: content;
font-size: clamp(1.2rem,3vw,1.6rem);
font-style: italic;
line-height: 1.4;
}
@supports not (display: grid) {
.cgl-01 .cgl-01__article {
max-inline-size: 65ch;
margin-inline: auto;
padding-inline: 1.5rem;
}
}.cgl-01,
.cgl-01 *,
.cgl-01 *::before,
.cgl-01 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-01 {
width: 100%;
min-height: 100vh;
--ink: oklch(0.24 0.02 60);
--paper: oklch(0.97 0.012 85);
--accent: oklch(0.55 0.14 40);
font-family: Georgia,'Times New Roman',serif;
color: var(--ink);
background: var(--paper);
}
.cgl-01 .cgl-01__article {
display: grid;
grid-template-columns: [full-start] minmax(1.5rem,1fr) [content-start] min(65ch,100% - 3rem) [content-end] minmax(1.5rem,1fr) [full-end];
row-gap: 1.4rem;
padding-block: 3rem;
}
.cgl-01 .cgl-01__article>* {
grid-column: content;
}
.cgl-01 .cgl-01__media--bleed,
.cgl-01 .cgl-01__quote--bleed {
grid-column: full;
}
.cgl-01 .cgl-01__kicker {
font-family: system-ui,sans-serif;
font-size: .72rem;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--accent);
margin-block-end: .6rem;
}
.cgl-01 h2 {
font-size: clamp(1.5rem,4vw,2.2rem);
line-height: 1.15;
text-wrap: balance;
}
.cgl-01 p {
font-size: 1.02rem;
line-height: 1.65;
}
.cgl-01 .cgl-01__ph {
inline-size: 100%;
aspect-ratio: 21/7;
background: linear-gradient(115deg,oklch(0.62 0.13 40),oklch(0.48 0.1 25) 50%,oklch(0.35 0.07 50)),repeating-linear-gradient(-45deg,transparent 0 18px,oklch(1 0 0/.06) 18px 36px);
background-blend-mode: overlay,normal;
}
.cgl-01 figcaption {
font-family: system-ui,sans-serif;
font-size: .75rem;
color: color-mix(in oklab,var(--ink) 60%,var(--paper));
padding-inline: 1.5rem;
padding-block-start: .5rem;
}
.cgl-01 .cgl-01__quote--bleed {
background: var(--ink);
color: var(--paper);
padding-block: 2.2rem;
padding-inline: 1.5rem;
display: grid;
grid-template-columns: inherit;
}
.cgl-01 .cgl-01__quote--bleed p {
grid-column: content;
font-size: clamp(1.2rem,3vw,1.6rem);
font-style: italic;
line-height: 1.4;
}
@supports not (display: grid) {
.cgl-01 .cgl-01__article {
max-inline-size: 65ch;
margin-inline: auto;
padding-inline: 1.5rem;
}
}/* No JavaScript — named grid lines create a 'content' and 'full' area; children opt into bleed with grid-column: full. */
/* No JavaScript — named grid lines create a 'content' and 'full' area; children opt into bleed with grid-column: full. */Here's a working CSS Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Full-Bleed Layout
Source: https://codefronts.com/layouts/css-grid-layouts/full-bleed-layout/
The layout every long-form article needs: body text locked to a readable 65ch measure, while images and pull-quotes break out to the full viewport width — no negative margins, no calc() hacks, no wrapper divs. One named-line grid does all of it, and any child can opt into full bleed with a single class.
## HTML
```html
<section class="cgl-01" aria-label="Full-bleed layout demo">
<article class="cgl-01__article">
<header class="cgl-01__head">
<p class="cgl-01__kicker">Layout Pattern № 01</p>
<h2>The measure stays put. The imagery doesn't.</h2>
</header>
<p>Body copy locks to a comfortable 65-character measure, centred by two elastic gutter tracks. Resize the page — the text column holds while the gutters breathe.</p>
<figure class="cgl-01__media cgl-01__media--bleed">
<div class="cgl-01__ph" role="img" aria-label="Full-width placeholder image"></div>
<figcaption>This figure spans grid-column: full — edge to edge, no negative margins.</figcaption>
</figure>
<p>Back in the content column, as if nothing happened. Any element can opt out with one class; everything else flows normally.</p>
<blockquote class="cgl-01__quote cgl-01__quote--bleed"><p>"Full bleed is a grid decision, not a margin hack."</p></blockquote>
</article>
</section>
```
## CSS
```css
.cgl-01,
.cgl-01 *,
.cgl-01 *::before,
.cgl-01 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-01 {
width: 100%;
min-height: 100vh;
--ink: oklch(0.24 0.02 60);
--paper: oklch(0.97 0.012 85);
--accent: oklch(0.55 0.14 40);
font-family: Georgia,'Times New Roman',serif;
color: var(--ink);
background: var(--paper);
}
.cgl-01 .cgl-01__article {
display: grid;
grid-template-columns: [full-start] minmax(1.5rem,1fr) [content-start] min(65ch,100% - 3rem) [content-end] minmax(1.5rem,1fr) [full-end];
row-gap: 1.4rem;
padding-block: 3rem;
}
.cgl-01 .cgl-01__article>* {
grid-column: content;
}
.cgl-01 .cgl-01__media--bleed,
.cgl-01 .cgl-01__quote--bleed {
grid-column: full;
}
.cgl-01 .cgl-01__kicker {
font-family: system-ui,sans-serif;
font-size: .72rem;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--accent);
margin-block-end: .6rem;
}
.cgl-01 h2 {
font-size: clamp(1.5rem,4vw,2.2rem);
line-height: 1.15;
text-wrap: balance;
}
.cgl-01 p {
font-size: 1.02rem;
line-height: 1.65;
}
.cgl-01 .cgl-01__ph {
inline-size: 100%;
aspect-ratio: 21/7;
background: linear-gradient(115deg,oklch(0.62 0.13 40),oklch(0.48 0.1 25) 50%,oklch(0.35 0.07 50)),repeating-linear-gradient(-45deg,transparent 0 18px,oklch(1 0 0/.06) 18px 36px);
background-blend-mode: overlay,normal;
}
.cgl-01 figcaption {
font-family: system-ui,sans-serif;
font-size: .75rem;
color: color-mix(in oklab,var(--ink) 60%,var(--paper));
padding-inline: 1.5rem;
padding-block-start: .5rem;
}
.cgl-01 .cgl-01__quote--bleed {
background: var(--ink);
color: var(--paper);
padding-block: 2.2rem;
padding-inline: 1.5rem;
display: grid;
grid-template-columns: inherit;
}
.cgl-01 .cgl-01__quote--bleed p {
grid-column: content;
font-size: clamp(1.2rem,3vw,1.6rem);
font-style: italic;
line-height: 1.4;
}
@supports not (display: grid) {
.cgl-01 .cgl-01__article {
max-inline-size: 65ch;
margin-inline: auto;
padding-inline: 1.5rem;
}
}
```
## JavaScript
```js
/* No JavaScript — named grid lines create a 'content' and 'full' area; children opt into bleed with grid-column: full. */
```Here's a working CSS Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Full-Bleed Layout
Source: https://codefronts.com/layouts/css-grid-layouts/full-bleed-layout/
The layout every long-form article needs: body text locked to a readable 65ch measure, while images and pull-quotes break out to the full viewport width — no negative margins, no calc() hacks, no wrapper divs. One named-line grid does all of it, and any child can opt into full bleed with a single class.
## HTML
```html
<section class="cgl-01" aria-label="Full-bleed layout demo">
<article class="cgl-01__article">
<header class="cgl-01__head">
<p class="cgl-01__kicker">Layout Pattern № 01</p>
<h2>The measure stays put. The imagery doesn't.</h2>
</header>
<p>Body copy locks to a comfortable 65-character measure, centred by two elastic gutter tracks. Resize the page — the text column holds while the gutters breathe.</p>
<figure class="cgl-01__media cgl-01__media--bleed">
<div class="cgl-01__ph" role="img" aria-label="Full-width placeholder image"></div>
<figcaption>This figure spans grid-column: full — edge to edge, no negative margins.</figcaption>
</figure>
<p>Back in the content column, as if nothing happened. Any element can opt out with one class; everything else flows normally.</p>
<blockquote class="cgl-01__quote cgl-01__quote--bleed"><p>"Full bleed is a grid decision, not a margin hack."</p></blockquote>
</article>
</section>
```
## CSS
```css
.cgl-01,
.cgl-01 *,
.cgl-01 *::before,
.cgl-01 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-01 {
width: 100%;
min-height: 100vh;
--ink: oklch(0.24 0.02 60);
--paper: oklch(0.97 0.012 85);
--accent: oklch(0.55 0.14 40);
font-family: Georgia,'Times New Roman',serif;
color: var(--ink);
background: var(--paper);
}
.cgl-01 .cgl-01__article {
display: grid;
grid-template-columns: [full-start] minmax(1.5rem,1fr) [content-start] min(65ch,100% - 3rem) [content-end] minmax(1.5rem,1fr) [full-end];
row-gap: 1.4rem;
padding-block: 3rem;
}
.cgl-01 .cgl-01__article>* {
grid-column: content;
}
.cgl-01 .cgl-01__media--bleed,
.cgl-01 .cgl-01__quote--bleed {
grid-column: full;
}
.cgl-01 .cgl-01__kicker {
font-family: system-ui,sans-serif;
font-size: .72rem;
letter-spacing: .18em;
text-transform: uppercase;
color: var(--accent);
margin-block-end: .6rem;
}
.cgl-01 h2 {
font-size: clamp(1.5rem,4vw,2.2rem);
line-height: 1.15;
text-wrap: balance;
}
.cgl-01 p {
font-size: 1.02rem;
line-height: 1.65;
}
.cgl-01 .cgl-01__ph {
inline-size: 100%;
aspect-ratio: 21/7;
background: linear-gradient(115deg,oklch(0.62 0.13 40),oklch(0.48 0.1 25) 50%,oklch(0.35 0.07 50)),repeating-linear-gradient(-45deg,transparent 0 18px,oklch(1 0 0/.06) 18px 36px);
background-blend-mode: overlay,normal;
}
.cgl-01 figcaption {
font-family: system-ui,sans-serif;
font-size: .75rem;
color: color-mix(in oklab,var(--ink) 60%,var(--paper));
padding-inline: 1.5rem;
padding-block-start: .5rem;
}
.cgl-01 .cgl-01__quote--bleed {
background: var(--ink);
color: var(--paper);
padding-block: 2.2rem;
padding-inline: 1.5rem;
display: grid;
grid-template-columns: inherit;
}
.cgl-01 .cgl-01__quote--bleed p {
grid-column: content;
font-size: clamp(1.2rem,3vw,1.6rem);
font-style: italic;
line-height: 1.4;
}
@supports not (display: grid) {
.cgl-01 .cgl-01__article {
max-inline-size: 65ch;
margin-inline: auto;
padding-inline: 1.5rem;
}
}
```
## JavaScript
```js
/* No JavaScript — named grid lines create a 'content' and 'full' area; children opt into bleed with grid-column: full. */
```How this works
The article is a three-column grid built with named lines: grid-template-columns: [full-start] minmax(1.5rem, 1fr) [content-start] min(65ch, 100% - 3rem) [content-end] minmax(1.5rem, 1fr) [full-end]. The outer minmax(1.5rem, 1fr) tracks are elastic gutters — never thinner than 1.5rem on phones, absorbing all leftover width on desktops so the middle column stays centred.
Every child defaults into the content column via .cgl-01 .cgl-01__article > * { grid-column: content; } — named lines create a named area for free. Anything with the --bleed modifier says grid-column: full and instantly spans edge to edge. That's the whole API: write flowing HTML, add one class to break out.
Make it yours
- Widen the measure by changing
65ch— ch units track your font, so it stays readable at any size. - Add a fourth 'popout' line pair (e.g.
[popout-start]atminmax(0, 6rem)) for images that break out slightly without going full width. - Tighten mobile gutters via the 1.5rem floor.
- Swap the serif stack for your brand type — the grid is type-agnostic.
Gotchas — read before shipping
- The
> *default assignment is essential — without it every child auto-places into the first (gutter) track. - Never put horizontal padding on the article itself; the gutter tracks ARE the padding. Doubling them up breaks the bleed.
- Images inside the bleed need
inline-size: 100%+object-fit: coveror they overflow their track.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 114+ | 17.5+ | 121+ | 114+ |
Floor set by oklch(), color-mix(), text-wrap as this demo is written. The core technique itself goes back further — Chrome 93+.
Named grid lines work everywhere grid does (2017+); min()/clamp() sizing needs 2020+ evergreens. oklch() colours are decorative and swap to hex for older targets.