22 CSS Split Screen Layouts04 / 22

Pure CSSMIT licensed

Hover Reveal Split

K-pop concert poster — hot pink + electric cyan + chrome. Two halves; hover/tap each to grow it from 50% to 70%, the other shrinks. Pure CSS via flex-grow transition; massive condensed type and chromatic-aberration headlines complete the album-cover feel.

Published Updated

Live Demo
Try it

The code

<section class="ss-kpop" aria-label="Album release split">
  <article class="ss-kpop-side ss-kpop-pink">
    <span class="ss-kpop-eye">SIDE A</span>
    <h2><span>NEON</span><span>HEART</span></h2>
    <p>Vol. 03 · Out now</p>
    <div class="ss-kpop-track">
      <span>01 ⟡ Midnight Drive</span>
      <span>02 ⟡ Lights Off</span>
      <span>03 ⟡ Pink Static</span>
    </div>
    <button type="button" class="ss-kpop-cta">▶ PLAY</button>
  </article>
  <article class="ss-kpop-side ss-kpop-cyan">
    <span class="ss-kpop-eye">SIDE B</span>
    <h2><span>CYBER</span><span>BLOOM</span></h2>
    <p>Vol. 03 · Out now</p>
    <div class="ss-kpop-track">
      <span>04 ⟡ Glass Hearts</span>
      <span>05 ⟡ Hologram</span>
      <span>06 ⟡ Echo Park</span>
    </div>
    <button type="button" class="ss-kpop-cta">▶ PLAY</button>
  </article>
</section>
.ss-kpop {
  width: 100%;
  display: flex;
  min-height: 100vh;
  font-family: 'Helvetica Neue', sans-serif;
  background: #0a0014;
  border-radius: 0;
  overflow: hidden;
  isolation: isolate;
}

.ss-kpop-side {
  flex: 1 1 50%;
  position: relative;
  padding: 36px 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  cursor: pointer;
  transition: flex-grow 0.4s cubic-bezier(0.32, 0.72, 0, 1);
  overflow: hidden;
  isolation: isolate;
}

.ss-kpop-side:hover,
.ss-kpop-side:focus-within {
  flex-grow: 1.6;
}

.ss-kpop-pink {
  background: repeating-linear-gradient(0deg, transparent 0 4px, rgba(0,0,0,0.05) 4px 5px), radial-gradient(60% 80% at 30% 30%, #ff52aa 0%, #c41560 100%);
  color: #fff;
  border-right: 2px solid #fff;
}

.ss-kpop-cyan {
  background: repeating-linear-gradient(0deg, transparent 0 4px, rgba(0,0,0,0.05) 4px 5px), radial-gradient(60% 80% at 70% 70%, #00e5ff 0%, #0080a8 100%);
  color: #0a0014;
}

.ss-kpop-pink::before,
.ss-kpop-cyan::before {
  content: '';
  position: absolute;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.85), rgba(255,255,255,0.2) 50%, transparent 70%);
  z-index: -1;
}

.ss-kpop-pink::before {
  top: -60px;
  right: -60px;
}

.ss-kpop-cyan::before {
  bottom: -60px;
  left: -60px;
}

.ss-kpop-eye {
  font-family: 'Courier New', monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.32em;
}

.ss-kpop-pink .ss-kpop-eye {
  color: #ffd400;
  text-shadow: 0 0 10px rgba(255,212,0,0.4);
}

.ss-kpop-cyan .ss-kpop-eye {
  color: #ff00aa;
}

.ss-kpop-side h2 {
  margin: 0;
  font-size: clamp(48px, 8vw, 96px);
  font-weight: 900;
  line-height: 0.85;
  letter-spacing: -0.04em;
  display: flex;
  flex-direction: column;
  font-style: italic;
}

.ss-kpop-side h2 span:nth-child(2) {
  align-self: flex-end;
}

.ss-kpop-pink h2 {
  color: #fff;
  text-shadow: -3px 0 0 #00e5ff, 3px 0 0 #ffd400;
}

.ss-kpop-cyan h2 {
  color: #0a0014;
  text-shadow: -3px 0 0 #ff52aa, 3px 0 0 #ffd400;
}

.ss-kpop-side p {
  margin: 0;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
}

.ss-kpop-pink p {
  color: #ffd400;
}

.ss-kpop-cyan p {
  color: #0a0014;
}

.ss-kpop-track {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 0;
  border-top: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  font-family: 'Courier New', monospace;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  opacity: 0.9;
}

.ss-kpop-cta {
  margin-top: auto;
  align-self: flex-start;
  padding: 12px 22px;
  background: #fff;
  color: #0a0014;
  border: 0;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.16em;
  cursor: pointer;
  transition: transform 0.12s;
}

.ss-kpop-pink .ss-kpop-cta {
  background: #ffd400;
  color: #c41560;
}

.ss-kpop-cyan .ss-kpop-cta {
  background: #ff52aa;
  color: #fff;
}

.ss-kpop-cta:hover {
  transform: scale(1.05);
}

@media (max-width: 720px) {
  .ss-kpop {
    flex-direction: column;
  }

  .ss-kpop-side {
    flex: 1 1 auto;
  }

  .ss-kpop-side:hover,
    .ss-kpop-side:focus-within {
    flex-grow: 1;
  }

  .ss-kpop-pink {
    border-right: 0;
    border-bottom: 2px solid #fff;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ss-kpop-side {
    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: Hover Reveal Split
Source: https://codefronts.com/layouts/css-split-screen/hover-reveal-split/

K-pop concert poster — hot pink + electric cyan + chrome. Two halves; hover/tap each to grow it from 50% to 70%, the other shrinks. Pure CSS via flex-grow transition; massive condensed type and chromatic-aberration headlines complete the album-cover feel.
## HTML
```html
<section class="ss-kpop" aria-label="Album release split">
  <article class="ss-kpop-side ss-kpop-pink">
    <span class="ss-kpop-eye">SIDE A</span>
    <h2><span>NEON</span><span>HEART</span></h2>
    <p>Vol. 03 · Out now</p>
    <div class="ss-kpop-track">
      <span>01 ⟡ Midnight Drive</span>
      <span>02 ⟡ Lights Off</span>
      <span>03 ⟡ Pink Static</span>
    </div>
    <button type="button" class="ss-kpop-cta">▶ PLAY</button>
  </article>
  <article class="ss-kpop-side ss-kpop-cyan">
    <span class="ss-kpop-eye">SIDE B</span>
    <h2><span>CYBER</span><span>BLOOM</span></h2>
    <p>Vol. 03 · Out now</p>
    <div class="ss-kpop-track">
      <span>04 ⟡ Glass Hearts</span>
      <span>05 ⟡ Hologram</span>
      <span>06 ⟡ Echo Park</span>
    </div>
    <button type="button" class="ss-kpop-cta">▶ PLAY</button>
  </article>
</section>
```
## CSS
```css
.ss-kpop {
  width: 100%;
  display: flex;
  min-height: 100vh;
  font-family: 'Helvetica Neue', sans-serif;
  background: #0a0014;
  border-radius: 0;
  overflow: hidden;
  isolation: isolate;
}

.ss-kpop-side {
  flex: 1 1 50%;
  position: relative;
  padding: 36px 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  cursor: pointer;
  transition: flex-grow 0.4s cubic-bezier(0.32, 0.72, 0, 1);
  overflow: hidden;
  isolation: isolate;
}

.ss-kpop-side:hover,
.ss-kpop-side:focus-within {
  flex-grow: 1.6;
}

.ss-kpop-pink {
  background: repeating-linear-gradient(0deg, transparent 0 4px, rgba(0,0,0,0.05) 4px 5px), radial-gradient(60% 80% at 30% 30%, #ff52aa 0%, #c41560 100%);
  color: #fff;
  border-right: 2px solid #fff;
}

.ss-kpop-cyan {
  background: repeating-linear-gradient(0deg, transparent 0 4px, rgba(0,0,0,0.05) 4px 5px), radial-gradient(60% 80% at 70% 70%, #00e5ff 0%, #0080a8 100%);
  color: #0a0014;
}

.ss-kpop-pink::before,
.ss-kpop-cyan::before {
  content: '';
  position: absolute;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.85), rgba(255,255,255,0.2) 50%, transparent 70%);
  z-index: -1;
}

.ss-kpop-pink::before {
  top: -60px;
  right: -60px;
}

.ss-kpop-cyan::before {
  bottom: -60px;
  left: -60px;
}

.ss-kpop-eye {
  font-family: 'Courier New', monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.32em;
}

.ss-kpop-pink .ss-kpop-eye {
  color: #ffd400;
  text-shadow: 0 0 10px rgba(255,212,0,0.4);
}

.ss-kpop-cyan .ss-kpop-eye {
  color: #ff00aa;
}

.ss-kpop-side h2 {
  margin: 0;
  font-size: clamp(48px, 8vw, 96px);
  font-weight: 900;
  line-height: 0.85;
  letter-spacing: -0.04em;
  display: flex;
  flex-direction: column;
  font-style: italic;
}

.ss-kpop-side h2 span:nth-child(2) {
  align-self: flex-end;
}

.ss-kpop-pink h2 {
  color: #fff;
  text-shadow: -3px 0 0 #00e5ff, 3px 0 0 #ffd400;
}

.ss-kpop-cyan h2 {
  color: #0a0014;
  text-shadow: -3px 0 0 #ff52aa, 3px 0 0 #ffd400;
}

.ss-kpop-side p {
  margin: 0;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
}

.ss-kpop-pink p {
  color: #ffd400;
}

.ss-kpop-cyan p {
  color: #0a0014;
}

.ss-kpop-track {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 0;
  border-top: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  font-family: 'Courier New', monospace;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  opacity: 0.9;
}

.ss-kpop-cta {
  margin-top: auto;
  align-self: flex-start;
  padding: 12px 22px;
  background: #fff;
  color: #0a0014;
  border: 0;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.16em;
  cursor: pointer;
  transition: transform 0.12s;
}

.ss-kpop-pink .ss-kpop-cta {
  background: #ffd400;
  color: #c41560;
}

.ss-kpop-cyan .ss-kpop-cta {
  background: #ff52aa;
  color: #fff;
}

.ss-kpop-cta:hover {
  transform: scale(1.05);
}

@media (max-width: 720px) {
  .ss-kpop {
    flex-direction: column;
  }

  .ss-kpop-side {
    flex: 1 1 auto;
  }

  .ss-kpop-side:hover,
    .ss-kpop-side:focus-within {
    flex-grow: 1;
  }

  .ss-kpop-pink {
    border-right: 0;
    border-bottom: 2px solid #fff;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ss-kpop-side {
    transition: none;
  }
}
```

How this works

The grid container uses grid-template-columns: 1fr 1fr at rest, then :has(.panel-a:hover) reshapes the parent to 1.85fr 1fr and :has(.panel-b:hover) flips it to 1fr 1.85fr. A transition: grid-template-columns 500ms cubic-bezier(0.65, 0, 0.35, 1) on the grid itself animates the column widths smoothly. This is the load-bearing trick: grid-template-columns became animatable in modern engines, so no JavaScript, no width hacks on the children, and the child content reflows naturally as its column expands. Each panel is a flex column with the album art centered and metadata anchored to the bottom edge.

Make it yours

  • Change the expansion ratio by tuning the two hover states. 1.5fr 1fr is a subtle reveal; 3fr 1fr is dramatic but crops the shrinking panel's content aggressively. Match your typography scale.
  • Retime the ease. The shipped cubic-bezier is quick and confident; try cubic-bezier(0.34, 1.56, 0.64, 1) for a slight overshoot bounce, or ease-out at 700ms for a slower cinematic feel.
  • Swap the palette by editing the two panel background variables. Bold pairings like magenta #e91e63 and cyan #00bcd4, or acid green #b8ff00 and violet #7b2cbf, hold the K-pop energy; muted pairs will read as corporate.
  • Add a keyboard equivalent by giving each panel tabindex='0' and mirroring the :hover rule with :focus-visible, so the expansion works via Tab key and not just mouse pointer.

Gotchas — read before shipping

  • Animating grid-template-columns is supported in Chrome 111+, Firefox 128+, and Safari 17.4+. Older Safari will snap between states with no transition. Ship a static equal split as the fallback and treat the animation as progressive enhancement.
  • The :has() selector is not available in Firefox before 121. Users on older Firefox get no hover response at all. Either accept the degradation or add a JavaScript polyfill that toggles a class on the parent.
  • The hover expand traps mobile users. Touch devices fire :hover on tap and lock the panel open until another element is tapped. Add @media (hover: hover) around the hover rule so touch devices see the static split.

Browser support

ChromeSafariFirefoxEdge
111+17.4+128+111+

Requires :has() (Chrome 105, Safari 15.4, Firefox 121) and animatable grid-template-columns. Older browsers snap between states; still functional.

Techniques used in this demo

Search CodeFronts

Loading…