22 CSS Image Galleries09 / 22
CSS Magazine Layout Gallery
A premium editorial spread: a bold full-bleed hero image with a headline set directly over it in a blend mode, flanked by an asymmetric grid of supporting shots. The magazine-style image layout design-led sites search for.
Published Updated
The code
<section class="gl-03" aria-label="Magazine layout gallery">
<div class="gl-03__grid">
<figure class="gl-03__hero">
<img src="https://loremflickr.com/900/700/travel,landscape?lock=301" alt="Winding coastal road at sunset" loading="lazy" decoding="async">
<figcaption class="gl-03__over">
<span class="gl-03__kicker">Issue 24 · Travel</span>
<h3 class="gl-03__title">The Long Way North</h3>
</figcaption>
</figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/harbor?lock=302" alt="Fishing harbour at first light" loading="lazy" decoding="async"><figcaption>Harbour mornings</figcaption></figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/cabin?lock=303" alt="Timber cabin among pines" loading="lazy" decoding="async"><figcaption>Off the map</figcaption></figure>
<figure class="gl-03__cell gl-03__cell--wide"><img src="https://loremflickr.com/900/450/road,mountain?lock=304" alt="Empty mountain highway" loading="lazy" decoding="async"><figcaption>Nothing but road ahead</figcaption></figure>
</div>
</section><section class="gl-03" aria-label="Magazine layout gallery">
<div class="gl-03__grid">
<figure class="gl-03__hero">
<img src="https://loremflickr.com/900/700/travel,landscape?lock=301" alt="Winding coastal road at sunset" loading="lazy" decoding="async">
<figcaption class="gl-03__over">
<span class="gl-03__kicker">Issue 24 · Travel</span>
<h3 class="gl-03__title">The Long Way North</h3>
</figcaption>
</figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/harbor?lock=302" alt="Fishing harbour at first light" loading="lazy" decoding="async"><figcaption>Harbour mornings</figcaption></figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/cabin?lock=303" alt="Timber cabin among pines" loading="lazy" decoding="async"><figcaption>Off the map</figcaption></figure>
<figure class="gl-03__cell gl-03__cell--wide"><img src="https://loremflickr.com/900/450/road,mountain?lock=304" alt="Empty mountain highway" loading="lazy" decoding="async"><figcaption>Nothing but road ahead</figcaption></figure>
</div>
</section>.gl-03,
.gl-03 *,
.gl-03 *::before,
.gl-03 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gl-03 ::selection {
background: #111;
color: #fff;
}
.gl-03 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
padding: 44px 20px;
background: #f7f5f0;
display: flex;
align-items: center;
justify-content: center;
}
.gl-03__grid {
width: min(940px,100%);
display: grid;
gap: 14px;
grid-template-columns: repeat(2,1fr);
grid-auto-rows: auto;
}
.gl-03__hero {
position: relative;
grid-column: 1 / 2;
grid-row: 1 / 3;
border-radius: 6px;
overflow: hidden;
}
.gl-03__hero img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 9/11;
}
.gl-03__over {
position: absolute;
inset: auto 0 0 0;
padding: 24px;
mix-blend-mode: difference;
color: #fff;
}
.gl-03__kicker {
font: 12px ui-monospace,Menlo,monospace;
letter-spacing: .2em;
text-transform: uppercase;
opacity: .9;
}
.gl-03__title {
margin-top: 8px;
font-family: Georgia,'Times New Roman',serif;
font-size: 40px;
line-height: 1.02;
font-weight: 700;
letter-spacing: -.01em;
text-wrap: balance;
}
.gl-03__cell {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #e7e3da;
}
.gl-03__cell img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 1/1;
transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.gl-03__cell--wide {
grid-column: 1 / 3;
}
.gl-03__cell--wide img {
aspect-ratio: 2/1;
}
.gl-03__cell figcaption {
position: absolute;
left: 0;
bottom: 0;
padding: 10px 14px;
color: #fff;
font-family: Georgia,serif;
font-style: italic;
font-size: 15px;
background: linear-gradient(0deg,rgba(0,0,0,.6),transparent);
width: 100%;
}
.gl-03__cell:hover img {
transform: scale(1.05);
}
@media (max-width: 640px) {
.gl-03__grid {
grid-template-columns: 1fr;
}
.gl-03__hero {
grid-column: 1;
grid-row: auto;
}
.gl-03__cell--wide {
grid-column: 1;
}
.gl-03__title {
font-size: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.gl-03__cell img {
transition: none;
}
}.gl-03,
.gl-03 *,
.gl-03 *::before,
.gl-03 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gl-03 ::selection {
background: #111;
color: #fff;
}
.gl-03 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
padding: 44px 20px;
background: #f7f5f0;
display: flex;
align-items: center;
justify-content: center;
}
.gl-03__grid {
width: min(940px,100%);
display: grid;
gap: 14px;
grid-template-columns: repeat(2,1fr);
grid-auto-rows: auto;
}
.gl-03__hero {
position: relative;
grid-column: 1 / 2;
grid-row: 1 / 3;
border-radius: 6px;
overflow: hidden;
}
.gl-03__hero img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 9/11;
}
.gl-03__over {
position: absolute;
inset: auto 0 0 0;
padding: 24px;
mix-blend-mode: difference;
color: #fff;
}
.gl-03__kicker {
font: 12px ui-monospace,Menlo,monospace;
letter-spacing: .2em;
text-transform: uppercase;
opacity: .9;
}
.gl-03__title {
margin-top: 8px;
font-family: Georgia,'Times New Roman',serif;
font-size: 40px;
line-height: 1.02;
font-weight: 700;
letter-spacing: -.01em;
text-wrap: balance;
}
.gl-03__cell {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #e7e3da;
}
.gl-03__cell img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 1/1;
transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.gl-03__cell--wide {
grid-column: 1 / 3;
}
.gl-03__cell--wide img {
aspect-ratio: 2/1;
}
.gl-03__cell figcaption {
position: absolute;
left: 0;
bottom: 0;
padding: 10px 14px;
color: #fff;
font-family: Georgia,serif;
font-style: italic;
font-size: 15px;
background: linear-gradient(0deg,rgba(0,0,0,.6),transparent);
width: 100%;
}
.gl-03__cell:hover img {
transform: scale(1.05);
}
@media (max-width: 640px) {
.gl-03__grid {
grid-template-columns: 1fr;
}
.gl-03__hero {
grid-column: 1;
grid-row: auto;
}
.gl-03__cell--wide {
grid-column: 1;
}
.gl-03__title {
font-size: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.gl-03__cell img {
transition: none;
}
}/* No JavaScript — CSS Grid + mix-blend-mode set editorial type over the hero image. */
/* No JavaScript — CSS Grid + mix-blend-mode set editorial type over the hero image. */Here's a working CSS Image Gallerie 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: CSS Magazine Layout Gallery
Source: https://codefronts.com/snippets/css-image-gallery/css-magazine-layout-gallery/
A premium editorial spread: a bold full-bleed hero image with a headline set directly over it in a blend mode, flanked by an asymmetric grid of supporting shots. The magazine-style image layout design-led sites search for.
## HTML
```html
<section class="gl-03" aria-label="Magazine layout gallery">
<div class="gl-03__grid">
<figure class="gl-03__hero">
<img src="https://loremflickr.com/900/700/travel,landscape?lock=301" alt="Winding coastal road at sunset" loading="lazy" decoding="async">
<figcaption class="gl-03__over">
<span class="gl-03__kicker">Issue 24 · Travel</span>
<h3 class="gl-03__title">The Long Way North</h3>
</figcaption>
</figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/harbor?lock=302" alt="Fishing harbour at first light" loading="lazy" decoding="async"><figcaption>Harbour mornings</figcaption></figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/cabin?lock=303" alt="Timber cabin among pines" loading="lazy" decoding="async"><figcaption>Off the map</figcaption></figure>
<figure class="gl-03__cell gl-03__cell--wide"><img src="https://loremflickr.com/900/450/road,mountain?lock=304" alt="Empty mountain highway" loading="lazy" decoding="async"><figcaption>Nothing but road ahead</figcaption></figure>
</div>
</section>
```
## CSS
```css
.gl-03,
.gl-03 *,
.gl-03 *::before,
.gl-03 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gl-03 ::selection {
background: #111;
color: #fff;
}
.gl-03 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
padding: 44px 20px;
background: #f7f5f0;
display: flex;
align-items: center;
justify-content: center;
}
.gl-03__grid {
width: min(940px,100%);
display: grid;
gap: 14px;
grid-template-columns: repeat(2,1fr);
grid-auto-rows: auto;
}
.gl-03__hero {
position: relative;
grid-column: 1 / 2;
grid-row: 1 / 3;
border-radius: 6px;
overflow: hidden;
}
.gl-03__hero img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 9/11;
}
.gl-03__over {
position: absolute;
inset: auto 0 0 0;
padding: 24px;
mix-blend-mode: difference;
color: #fff;
}
.gl-03__kicker {
font: 12px ui-monospace,Menlo,monospace;
letter-spacing: .2em;
text-transform: uppercase;
opacity: .9;
}
.gl-03__title {
margin-top: 8px;
font-family: Georgia,'Times New Roman',serif;
font-size: 40px;
line-height: 1.02;
font-weight: 700;
letter-spacing: -.01em;
text-wrap: balance;
}
.gl-03__cell {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #e7e3da;
}
.gl-03__cell img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 1/1;
transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.gl-03__cell--wide {
grid-column: 1 / 3;
}
.gl-03__cell--wide img {
aspect-ratio: 2/1;
}
.gl-03__cell figcaption {
position: absolute;
left: 0;
bottom: 0;
padding: 10px 14px;
color: #fff;
font-family: Georgia,serif;
font-style: italic;
font-size: 15px;
background: linear-gradient(0deg,rgba(0,0,0,.6),transparent);
width: 100%;
}
.gl-03__cell:hover img {
transform: scale(1.05);
}
@media (max-width: 640px) {
.gl-03__grid {
grid-template-columns: 1fr;
}
.gl-03__hero {
grid-column: 1;
grid-row: auto;
}
.gl-03__cell--wide {
grid-column: 1;
}
.gl-03__title {
font-size: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.gl-03__cell img {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — CSS Grid + mix-blend-mode set editorial type over the hero image. */
```Here's a working CSS Image Gallerie 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: CSS Magazine Layout Gallery
Source: https://codefronts.com/snippets/css-image-gallery/css-magazine-layout-gallery/
A premium editorial spread: a bold full-bleed hero image with a headline set directly over it in a blend mode, flanked by an asymmetric grid of supporting shots. The magazine-style image layout design-led sites search for.
## HTML
```html
<section class="gl-03" aria-label="Magazine layout gallery">
<div class="gl-03__grid">
<figure class="gl-03__hero">
<img src="https://loremflickr.com/900/700/travel,landscape?lock=301" alt="Winding coastal road at sunset" loading="lazy" decoding="async">
<figcaption class="gl-03__over">
<span class="gl-03__kicker">Issue 24 · Travel</span>
<h3 class="gl-03__title">The Long Way North</h3>
</figcaption>
</figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/harbor?lock=302" alt="Fishing harbour at first light" loading="lazy" decoding="async"><figcaption>Harbour mornings</figcaption></figure>
<figure class="gl-03__cell"><img src="https://loremflickr.com/500/500/cabin?lock=303" alt="Timber cabin among pines" loading="lazy" decoding="async"><figcaption>Off the map</figcaption></figure>
<figure class="gl-03__cell gl-03__cell--wide"><img src="https://loremflickr.com/900/450/road,mountain?lock=304" alt="Empty mountain highway" loading="lazy" decoding="async"><figcaption>Nothing but road ahead</figcaption></figure>
</div>
</section>
```
## CSS
```css
.gl-03,
.gl-03 *,
.gl-03 *::before,
.gl-03 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.gl-03 ::selection {
background: #111;
color: #fff;
}
.gl-03 {
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
padding: 44px 20px;
background: #f7f5f0;
display: flex;
align-items: center;
justify-content: center;
}
.gl-03__grid {
width: min(940px,100%);
display: grid;
gap: 14px;
grid-template-columns: repeat(2,1fr);
grid-auto-rows: auto;
}
.gl-03__hero {
position: relative;
grid-column: 1 / 2;
grid-row: 1 / 3;
border-radius: 6px;
overflow: hidden;
}
.gl-03__hero img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 9/11;
}
.gl-03__over {
position: absolute;
inset: auto 0 0 0;
padding: 24px;
mix-blend-mode: difference;
color: #fff;
}
.gl-03__kicker {
font: 12px ui-monospace,Menlo,monospace;
letter-spacing: .2em;
text-transform: uppercase;
opacity: .9;
}
.gl-03__title {
margin-top: 8px;
font-family: Georgia,'Times New Roman',serif;
font-size: 40px;
line-height: 1.02;
font-weight: 700;
letter-spacing: -.01em;
text-wrap: balance;
}
.gl-03__cell {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #e7e3da;
}
.gl-03__cell img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 1/1;
transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.gl-03__cell--wide {
grid-column: 1 / 3;
}
.gl-03__cell--wide img {
aspect-ratio: 2/1;
}
.gl-03__cell figcaption {
position: absolute;
left: 0;
bottom: 0;
padding: 10px 14px;
color: #fff;
font-family: Georgia,serif;
font-style: italic;
font-size: 15px;
background: linear-gradient(0deg,rgba(0,0,0,.6),transparent);
width: 100%;
}
.gl-03__cell:hover img {
transform: scale(1.05);
}
@media (max-width: 640px) {
.gl-03__grid {
grid-template-columns: 1fr;
}
.gl-03__hero {
grid-column: 1;
grid-row: auto;
}
.gl-03__cell--wide {
grid-column: 1;
}
.gl-03__title {
font-size: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.gl-03__cell img {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — CSS Grid + mix-blend-mode set editorial type over the hero image. */
```How this works
An asymmetric CSS Grid places a large hero cell alongside smaller supporting cells. The headline sits over the hero and uses mix-blend-mode: difference so the type stays legible over any part of the photo by inverting against it — the trick print-inspired layouts rely on.
Overlapping is intentional: a kicker and byline break the grid alignment slightly (negative margins / grid overlap) for an editorial, un-boxy feel, while every image remains a semantic <figure>/<figcaption>.
Make it yours
- Rebalance the spread by changing the hero's
grid-column/grid-rowspan. - Try
mix-blend-mode: exclusionoroverlayfor different type-over-image moods. - Swap the serif display face for your editorial brand font.
- Add a pull-quote cell that overlaps the hero edge for more grid-breaking drama.
Gotchas — read before shipping
mix-blend-modeover a photo can drop contrast on mid-tone areas — keep a text-shadow or scrim fallback for accessibility.- Blend-mode legibility varies with the image; test the headline against the actual photo, not a placeholder.
- Give the hero a defined aspect-ratio so the overlaid headline position stays predictable.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 114+ | 17.5+ | 121+ | 114+ |
Floor set by text-wrap as this demo is written. The core technique itself goes back further — Chrome 41+.
CSS Grid + mix-blend-mode — supported across all current browsers.