22 CSS Split Screen Layouts18 / 22
Quad Photo Split
Photography portfolio quad split — charcoal frame with four photo accents (sage / clay / mustard / bone). Hover any tile to expand it; the others contract. CSS grid with :has() on the wrapper to drive the proportions.
Published Updated
The code
<section class="ss-quad" aria-label="Photography portfolio quad">
<article
class="ss-quad-tile"
tabindex="0"
data-tile="1"
style="--bg: linear-gradient(135deg, #7a8a6a 0%, #4a5a3a 100%)"
>
<span class="ss-quad-num">01</span>
<h3>Field Notes</h3>
<p>Coastal Oregon, autumn 2025</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="2"
style="--bg: linear-gradient(135deg, #c45a3c 0%, #8a3818 100%)"
>
<span class="ss-quad-num">02</span>
<h3>Clay Walls</h3>
<p>Marrakech rooftops at noon</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="3"
style="--bg: linear-gradient(135deg, #e8b04a 0%, #b8842a 100%)"
>
<span class="ss-quad-num">03</span>
<h3>Yellow Hour</h3>
<p>Tuscan vineyards in late September</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="4"
style="--bg: linear-gradient(135deg, #e0d4c0 0%, #a89880 100%)"
>
<span class="ss-quad-num">04</span>
<h3>Bone & Stone</h3>
<p>Atacama mineral landscapes</p>
</article>
</section><section class="ss-quad" aria-label="Photography portfolio quad">
<article
class="ss-quad-tile"
tabindex="0"
data-tile="1"
style="--bg: linear-gradient(135deg, #7a8a6a 0%, #4a5a3a 100%)"
>
<span class="ss-quad-num">01</span>
<h3>Field Notes</h3>
<p>Coastal Oregon, autumn 2025</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="2"
style="--bg: linear-gradient(135deg, #c45a3c 0%, #8a3818 100%)"
>
<span class="ss-quad-num">02</span>
<h3>Clay Walls</h3>
<p>Marrakech rooftops at noon</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="3"
style="--bg: linear-gradient(135deg, #e8b04a 0%, #b8842a 100%)"
>
<span class="ss-quad-num">03</span>
<h3>Yellow Hour</h3>
<p>Tuscan vineyards in late September</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="4"
style="--bg: linear-gradient(135deg, #e0d4c0 0%, #a89880 100%)"
>
<span class="ss-quad-num">04</span>
<h3>Bone & Stone</h3>
<p>Atacama mineral landscapes</p>
</article>
</section>.ss-quad {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
min-height: 100vh;
font-family: 'Inter', system-ui, sans-serif;
background: #1a1a1a;
gap: 2px;
border-radius: 0;
overflow: hidden;
border: 2px solid #1a1a1a;
}
.ss-quad-tile {
position: relative;
background: var(--bg);
padding: 28px 28px;
display: flex;
flex-direction: column;
gap: 10px;
color: #fff;
cursor: pointer;
transition: transform 0.32s ease, box-shadow 0.32s ease;
isolation: isolate;
overflow: hidden;
}
.ss-quad-tile::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, transparent 60%, rgba(0,0,0,0.4) 100%);
pointer-events: none;
z-index: -1;
}
.ss-quad-tile:hover,
.ss-quad-tile:focus-visible {
transform: scale(1.02);
z-index: 2;
box-shadow: 0 14px 40px rgba(0,0,0,0.5);
outline: none;
}
.ss-quad:has(.ss-quad-tile:hover) .ss-quad-tile:not(:hover),
.ss-quad:has(.ss-quad-tile:focus-visible) .ss-quad-tile:not(:focus-visible) {
filter: grayscale(0.7) brightness(0.7);
}
.ss-quad-num {
font-family: 'Courier New', monospace;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.28em;
color: rgba(255,255,255,0.6);
}
.ss-quad-tile h3 {
margin: auto 0 0;
font-family: 'Cormorant Garamond', serif;
font-size: clamp(24px, 3.5vw, 40px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.02em;
font-style: italic;
}
.ss-quad-tile p {
margin: 0;
font-size: 13px;
letter-spacing: 0.04em;
opacity: 0.9;
}
@media (max-width: 720px) {
.ss-quad {
grid-template-columns: 1fr;
grid-template-rows: repeat(4, 1fr);
}
}
@media (prefers-reduced-motion: reduce) {
.ss-quad-tile {
transition: none;
}
}.ss-quad {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
min-height: 100vh;
font-family: 'Inter', system-ui, sans-serif;
background: #1a1a1a;
gap: 2px;
border-radius: 0;
overflow: hidden;
border: 2px solid #1a1a1a;
}
.ss-quad-tile {
position: relative;
background: var(--bg);
padding: 28px 28px;
display: flex;
flex-direction: column;
gap: 10px;
color: #fff;
cursor: pointer;
transition: transform 0.32s ease, box-shadow 0.32s ease;
isolation: isolate;
overflow: hidden;
}
.ss-quad-tile::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, transparent 60%, rgba(0,0,0,0.4) 100%);
pointer-events: none;
z-index: -1;
}
.ss-quad-tile:hover,
.ss-quad-tile:focus-visible {
transform: scale(1.02);
z-index: 2;
box-shadow: 0 14px 40px rgba(0,0,0,0.5);
outline: none;
}
.ss-quad:has(.ss-quad-tile:hover) .ss-quad-tile:not(:hover),
.ss-quad:has(.ss-quad-tile:focus-visible) .ss-quad-tile:not(:focus-visible) {
filter: grayscale(0.7) brightness(0.7);
}
.ss-quad-num {
font-family: 'Courier New', monospace;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.28em;
color: rgba(255,255,255,0.6);
}
.ss-quad-tile h3 {
margin: auto 0 0;
font-family: 'Cormorant Garamond', serif;
font-size: clamp(24px, 3.5vw, 40px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.02em;
font-style: italic;
}
.ss-quad-tile p {
margin: 0;
font-size: 13px;
letter-spacing: 0.04em;
opacity: 0.9;
}
@media (max-width: 720px) {
.ss-quad {
grid-template-columns: 1fr;
grid-template-rows: repeat(4, 1fr);
}
}
@media (prefers-reduced-motion: reduce) {
.ss-quad-tile {
transition: none;
}
}Here's a working CSS Split Screen 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: Quad Photo Split
Source: https://codefronts.com/layouts/css-split-screen/quad-photo-split/
Photography portfolio quad split — charcoal frame with four photo accents (sage / clay / mustard / bone). Hover any tile to expand it; the others contract. CSS grid with :has() on the wrapper to drive the proportions.
## HTML
```html
<section class="ss-quad" aria-label="Photography portfolio quad">
<article
class="ss-quad-tile"
tabindex="0"
data-tile="1"
style="--bg: linear-gradient(135deg, #7a8a6a 0%, #4a5a3a 100%)"
>
<span class="ss-quad-num">01</span>
<h3>Field Notes</h3>
<p>Coastal Oregon, autumn 2025</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="2"
style="--bg: linear-gradient(135deg, #c45a3c 0%, #8a3818 100%)"
>
<span class="ss-quad-num">02</span>
<h3>Clay Walls</h3>
<p>Marrakech rooftops at noon</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="3"
style="--bg: linear-gradient(135deg, #e8b04a 0%, #b8842a 100%)"
>
<span class="ss-quad-num">03</span>
<h3>Yellow Hour</h3>
<p>Tuscan vineyards in late September</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="4"
style="--bg: linear-gradient(135deg, #e0d4c0 0%, #a89880 100%)"
>
<span class="ss-quad-num">04</span>
<h3>Bone & Stone</h3>
<p>Atacama mineral landscapes</p>
</article>
</section>
```
## CSS
```css
.ss-quad {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
min-height: 100vh;
font-family: 'Inter', system-ui, sans-serif;
background: #1a1a1a;
gap: 2px;
border-radius: 0;
overflow: hidden;
border: 2px solid #1a1a1a;
}
.ss-quad-tile {
position: relative;
background: var(--bg);
padding: 28px 28px;
display: flex;
flex-direction: column;
gap: 10px;
color: #fff;
cursor: pointer;
transition: transform 0.32s ease, box-shadow 0.32s ease;
isolation: isolate;
overflow: hidden;
}
.ss-quad-tile::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, transparent 60%, rgba(0,0,0,0.4) 100%);
pointer-events: none;
z-index: -1;
}
.ss-quad-tile:hover,
.ss-quad-tile:focus-visible {
transform: scale(1.02);
z-index: 2;
box-shadow: 0 14px 40px rgba(0,0,0,0.5);
outline: none;
}
.ss-quad:has(.ss-quad-tile:hover) .ss-quad-tile:not(:hover),
.ss-quad:has(.ss-quad-tile:focus-visible) .ss-quad-tile:not(:focus-visible) {
filter: grayscale(0.7) brightness(0.7);
}
.ss-quad-num {
font-family: 'Courier New', monospace;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.28em;
color: rgba(255,255,255,0.6);
}
.ss-quad-tile h3 {
margin: auto 0 0;
font-family: 'Cormorant Garamond', serif;
font-size: clamp(24px, 3.5vw, 40px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.02em;
font-style: italic;
}
.ss-quad-tile p {
margin: 0;
font-size: 13px;
letter-spacing: 0.04em;
opacity: 0.9;
}
@media (max-width: 720px) {
.ss-quad {
grid-template-columns: 1fr;
grid-template-rows: repeat(4, 1fr);
}
}
@media (prefers-reduced-motion: reduce) {
.ss-quad-tile {
transition: none;
}
}
```Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Split Screen 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: Quad Photo Split
Source: https://codefronts.com/layouts/css-split-screen/quad-photo-split/
Photography portfolio quad split — charcoal frame with four photo accents (sage / clay / mustard / bone). Hover any tile to expand it; the others contract. CSS grid with :has() on the wrapper to drive the proportions.
## HTML
```html
<section class="ss-quad" aria-label="Photography portfolio quad">
<article
class="ss-quad-tile"
tabindex="0"
data-tile="1"
style="--bg: linear-gradient(135deg, #7a8a6a 0%, #4a5a3a 100%)"
>
<span class="ss-quad-num">01</span>
<h3>Field Notes</h3>
<p>Coastal Oregon, autumn 2025</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="2"
style="--bg: linear-gradient(135deg, #c45a3c 0%, #8a3818 100%)"
>
<span class="ss-quad-num">02</span>
<h3>Clay Walls</h3>
<p>Marrakech rooftops at noon</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="3"
style="--bg: linear-gradient(135deg, #e8b04a 0%, #b8842a 100%)"
>
<span class="ss-quad-num">03</span>
<h3>Yellow Hour</h3>
<p>Tuscan vineyards in late September</p>
</article>
<article
class="ss-quad-tile"
tabindex="0"
data-tile="4"
style="--bg: linear-gradient(135deg, #e0d4c0 0%, #a89880 100%)"
>
<span class="ss-quad-num">04</span>
<h3>Bone & Stone</h3>
<p>Atacama mineral landscapes</p>
</article>
</section>
```
## CSS
```css
.ss-quad {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
min-height: 100vh;
font-family: 'Inter', system-ui, sans-serif;
background: #1a1a1a;
gap: 2px;
border-radius: 0;
overflow: hidden;
border: 2px solid #1a1a1a;
}
.ss-quad-tile {
position: relative;
background: var(--bg);
padding: 28px 28px;
display: flex;
flex-direction: column;
gap: 10px;
color: #fff;
cursor: pointer;
transition: transform 0.32s ease, box-shadow 0.32s ease;
isolation: isolate;
overflow: hidden;
}
.ss-quad-tile::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, transparent 60%, rgba(0,0,0,0.4) 100%);
pointer-events: none;
z-index: -1;
}
.ss-quad-tile:hover,
.ss-quad-tile:focus-visible {
transform: scale(1.02);
z-index: 2;
box-shadow: 0 14px 40px rgba(0,0,0,0.5);
outline: none;
}
.ss-quad:has(.ss-quad-tile:hover) .ss-quad-tile:not(:hover),
.ss-quad:has(.ss-quad-tile:focus-visible) .ss-quad-tile:not(:focus-visible) {
filter: grayscale(0.7) brightness(0.7);
}
.ss-quad-num {
font-family: 'Courier New', monospace;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.28em;
color: rgba(255,255,255,0.6);
}
.ss-quad-tile h3 {
margin: auto 0 0;
font-family: 'Cormorant Garamond', serif;
font-size: clamp(24px, 3.5vw, 40px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.02em;
font-style: italic;
}
.ss-quad-tile p {
margin: 0;
font-size: 13px;
letter-spacing: 0.04em;
opacity: 0.9;
}
@media (max-width: 720px) {
.ss-quad {
grid-template-columns: 1fr;
grid-template-rows: repeat(4, 1fr);
}
}
@media (prefers-reduced-motion: reduce) {
.ss-quad-tile {
transition: none;
}
}
```How this works
The wrapper is a 2×2 grid viagrid-template-columns: 1fr 1fr and grid-template-rows: 1fr 1fr with a small gap. Each cell sets aspect-ratio: 1 so tiles stay square regardless of viewport, and position: relative; overflow: hidden to contain painted content. The photo placeholder is a stacked linear-gradient sky-to-ground base with an absolutely positioned silhouette shape built from border-radius and clip-path. The caption overlay is a bottom-anchored strip with position: absolute; inset: auto 0 0 0, a translucent dark background, and backdrop-filter: blur(8px). Each tile uses a scoped --accent for palette variation.Make it yours
- Change grid shape to 3×2 or 4×1 by editing the two
grid-template-*lines;aspect-ratio: 1keeps tiles square, or swap to4/3or3/2for a wider portfolio feel. - Add a hover reveal on the caption by keeping it hidden with
transform: translateY(100%)and sliding in on:hoverwith atransition; pair with a:focus-withinselector for keyboard parity. - Give each tile a distinct palette by setting
--accentper:nth-child()and referencing it in both the gradient stops and the caption border. - Swap gradient placeholders for real images with
<img>atwidth: 100%; height: 100%; object-fit: cover; theaspect-ratioon the cell keeps layout stable during image load.
Gotchas — read before shipping
aspect-ratioyields to explicitheight; if a parent forces a height the ratio is ignored and tiles distort. Keep the wrapper height-free or usemin-heightinstead.- Below ~500px viewport the 2×2 grid produces tiny tiles that hide caption text; add a
@media (max-width: 500px)breakpoint that collapses to a single column with talleraspect-ratio: 3/2tiles. backdrop-filteron caption strips is expensive on low-end mobile GPUs; if you see jank while scrolling, swap to a solidrgba(0,0,0,0.55)background and drop the blur.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 105+ | 15.4+ | 121+ | 105+ |
Floor set by :has() as this demo is written. The core technique itself goes back further — Chrome any modern.
Grid, aspect-ratio, gradients, clip-path — Baseline. backdrop-filter for caption strips: Baseline 2023. Gate any hover reveal transition behind prefers-reduced-motion.