22 CSS Split Screen Layouts

22 hand-coded CSS split-screen layouts for tier-1 SaaS landing heroes (Stripe / Linear / Framer / Vercel / Notion), fintech sign-in flows (Coinbase / Ramp / Wealthfront), real-estate property compares (Zillow / Redfin / Compass / Realtor.com), editorial magazine spreads (Vogue / Kinfolk / NYT), and scroll-storytelling long-reads (Pudding / Guardian / NYT interactives) — classic 50/50, diagonal clip-path polygon, hover-reveal grid animation, before/after slider, sticky-scroll compare, 3D perspective keynote, plus editorial hero, quad photo grid, curved seam, Z-pattern card, and magazine crossover. 20 Pure CSS + 2 vanilla-JS under 20 lines each — zero dependencies vs Aceternity ($299/yr, 45KB), Magic UI, ReactBits, shadcn split. Modern CSS surface: animatable grid-template-columns, :has() relational state, clip-path: polygon(), transform-style: preserve-3d, position: sticky, container queries, animation-timeline: view(). Scoped under .ss-XX-NN for no-collision pasting, prefers-reduced-motion guarded per WCAG 2.3.3, framework-agnostic (React / Next.js App Router / Vue / Svelte / Astro / Tailwind v4 / shadcn).

21 pure CSS1 light JSPublished

Related20 CSS Diagonal Sections31 CSS Hero Sections15 CSS Flexbox Layouts30 CSS Login Forms

Editorial Restaurant — preview
01 / 22Pure CSS

Editorial Restaurant

Editorial restaurant menu — cream paper, olive-green typography, burgundy accents. Classic 50/50 split with food photography on the left (CSS-painted plate) and the menu on the right. Serif headlines, dotted-leader pricing, the printed-menu aesthetic.

PublishedUpdated

Diagonal Split — preview
02 / 22Pure CSS

Diagonal Split

Sport magazine — pitch black with electric-orange diagonal cut and concrete-grey supporting tones. Headline punches through the diagonal seam. Pure CSS via clip-path: polygon() for the angled wedge; oversized condensed display type sells the impact.

PublishedUpdated

Wine Cellar — preview
03 / 22Pure CSS

Wine Cellar

Wine cellar boutique — deep burgundy with gold-leaf accents and cream label typography. Asymmetric 60/40 split: a single CSS-painted bottle on the left, vintage tasting notes on the right. Real <dl> for the vintage details.

PublishedUpdated

Hover Reveal Split — preview
04 / 22Pure CSS

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.

PublishedUpdated

Coffee Triptych — preview
05 / 22Pure CSS

Coffee Triptych

Three coffee blends side-by-side — espresso brown, cream, copper. Three vertical panels in a single row, each with its own roast story. Hover any panel to reveal the tasting notes. CSS grid with 1fr 1fr 1fr and a shared expand-on-hover behavior.

PublishedUpdated

Curved Split — preview
06 / 22Pure CSS

Curved Split

Surf brand — ocean teal meets sand beige with a wave-curved seam, sunset-coral CTA. Pure CSS curve via border-radius and a generous clip-path. The two halves never share a straight line — feels organic, beach-y, hand-shaped.

PublishedUpdated

Asymmetric 70/30 — preview
07 / 22Pure CSS

Asymmetric 70/30

Architecture portfolio — warm grey concrete + ivory + black accents. Asymmetric 70/30 split: a single hero project on the left, oversized index numbers on the right. Print-magazine spread vibe; thin hairlines do all the structuring.

PublishedUpdated

Stepped Diagonal — preview
08 / 22Pure CSS

Stepped Diagonal

Streetwear brand drop — mustard yellow + asphalt black + neon pink. Stepped diagonal cut between two halves, sticker-graphic typography, drop-countdown badge. The kind of split a sneaker brand uses to announce a Friday release.

PublishedUpdated

Jewelry Sign-in — preview
09 / 22Pure CSS

Jewelry Sign-in

Jewelry boutique sign-in — champagne cream + obsidian black + rose gold. Brand on one side, sign-in form on the other. The kind of split-screen Tiffany would commission. Real <form> with proper labels and autocomplete tokens.

PublishedUpdated

Before/After Slider — preview
10 / 22Light JS

Before/After Slider

Skincare brand before/after — clinical white + millennial pink + sage green. Drag the native <input type="range"> to wipe between two states. Pure CSS via :has() on the input value (modern browsers); falls back to a clean static split otherwise.

PublishedUpdated

Two Seasons — preview
11 / 22Pure CSS

Two Seasons

Two seasons of fashion — autumn (rust + ochre + olive) on one side, winter (steel + cobalt + ash) on the other. Click either label to slide the other half open. Pure CSS via radio inputs + sibling selectors; no JS.

PublishedUpdated

Music App Toggle — preview
12 / 22Pure CSS

Music App Toggle

Music app — deep purple + neon mint + black vinyl. Toggle between equal-split (album list) and focus-mode (now playing dominates). Hidden checkbox + :has(:checked) on the grid template; everything else is CSS.

PublishedUpdated

Real-estate Compare — preview
13 / 22Pure CSS

Real-estate Compare

Compare two properties — terracotta + olive + warm beige. Two cards side by side, each with hero number, key stats, and price. Hover any side to scale up; the other dims subtly. CSS transform + opacity transitions.

PublishedUpdated

Detective Novel — preview
14 / 22Pure CSS

Detective Novel

Detective novel cover — burnt orange + ink black + parchment cream. A diagonal mask wipes between the cover image and a synopsis on hover. Mystery noir aesthetic with serif type, thin gold rules, and a deliberately distressed paper texture.

PublishedUpdated

Mediterranean Travel — preview
15 / 22Pure CSS

Mediterranean Travel

Travel agency hero — Mediterranean blue + ochre + white limewash. Parallax-feel split with layered cliff/sea/sun shapes on one side and a destination card on the other. Pure CSS animations drift the sun and sea slowly.

PublishedUpdated

Glitch Arcade — preview
16 / 22Pure CSS

Glitch Arcade

Cyber-arcade split — deep purple base with neon-green and magenta. Continuous glitch overlay shifts the colored layers in/out across the seam. Different from Tokyo Neon (sidebars): this is dystopian-arcade not tokyo-pop, dark green vs hot magenta.

PublishedUpdated

Coffee Origin Story — preview
17 / 22Pure CSS

Coffee Origin Story

Coffee origin story — kraft brown + cream + gold leaf. Two-column editorial: hero image map on the left, a numbered story of the bean's journey on the right. Real <ol> with custom counter styling.

PublishedUpdated

Quad Photo Split — preview
18 / 22Pure CSS

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.

PublishedUpdated

Recipe Reveal — preview
19 / 22Pure CSS

Recipe Reveal

Recipe book — terracotta + sage + butter yellow. Two halves: a recipe header on top, ingredients/method below. On smaller viewports the layout stacks; the right half "reveals" the method. Real <ul> + <ol> for ingredients and steps.

PublishedUpdated

Pet Adoption Z — preview
20 / 22Pure CSS

Pet Adoption Z

Pet adoption — grass green + sky blue + sun yellow. Z-pattern: image left → text right → image right → text left, but expressed as a 2×2 grid that creates an interlocking flow. Friendly, optimistic, full of CSS-painted dog and cat illustrations.

PublishedUpdated

Magazine Crossover — preview
21 / 22Pure CSS

Magazine Crossover

Editorial magazine spread — newspaper black on cream with a single spot color (cobalt blue). Oversized italic headline crosses the seam between two halves; pull-quote on the right intrudes into the left photo zone. The kind of layout you see on a New York Times Magazine longread.

PublishedUpdated

3D Perspective Keynote — preview
22 / 22Pure CSS

3D Perspective Keynote

Tech keynote — deep navy + holographic gradient + chrome. Two halves tilted in 3D space via perspective + rotateY; left panel angles toward viewer, right panel angles away. The "Apple event slide" feel — premium, sleek, almost cinematic.

PublishedUpdated

FAQ

Frequently asked questions

How do you pick the right CSS split-screen pattern for your page?
Start with the job the section does. If two options need direct comparison — two properties, two plans, before/after — use a symmetric 50/50 grid so the eye can dart between them without one side pulling harder. If one side is the subject and the other is context, use 70/30 or 60/40; the wide side gets the headline, the narrow side gets metadata. If the section is a hero with a visual on one side and a form or CTA on the other, 55/45 in favor of the visual tests best for conversion on tier-1 SaaS pages. Avoid symmetric 50/50 for hero-with-form — it makes the form feel like it's competing with the visual. For editorial storytelling with a large image and long-form text, use 45/55 in favor of the text and let a single hero image cross the boundary with overflow: visible; the visual break signals magazine-style prestige. For before/after comparisons where users need to see both states at once, use a single overlay with a draggable clip-path slider rather than two side-by-side panels — a slider ships two full views in the same box and lets users control the reveal precisely. Every pattern in this collection uses CSS Grid on the outer wrapper with a @media (max-width: 640px) { grid-template-columns: 1fr } block so mobile stacks vertically.
How do I animate the split ratio on hover or click without JavaScript?
Modern CSS makes grid-template-columns animatable when both keyframes use the same unit type — same fr, or same percentages. Set the wrapper to display: grid; grid-template-columns: 1fr 1fr; transition: grid-template-columns 400ms cubic-bezier(0.4, 0, 0.2, 1), then on hover or via :has(:checked) retarget to 1.85fr 1fr. The grid tracks tween smoothly and the child content reflows as its column expands. This lands in Chrome 111+, Firefox 128+, Safari 17.4+. On older browsers the resize snaps between states with no animation — the interaction still works, just abruptly, which reads as intentional design. Pair with @media (hover: hover) to skip the hover trigger on touch devices (where :hover sticks after tap), and add a keyboard equivalent by giving each panel tabindex='0' and mirroring the :hover rule with :focus-visible. For radio/checkbox-driven toggles like the Two Seasons demo, hide the input with position: absolute; opacity: 0, style a label as the visible target, and gate the parent grid with .wrapper:has(#option:checked) { grid-template-columns: 65% 35%; }. Wrap the transition in @media (prefers-reduced-motion: no-preference) so vestibular-sensitive users get an instant snap rather than a swept resize.
How do I build a diagonal split with CSS clip-path polygon?
Two absolutely positioned panels sit inside a position: relative stage with isolation: isolate so the stacking context stays contained. Both panels fill the stage with inset: 0. The first panel gets clip-path: polygon(0 0, 60% 0, 40% 100%, 0 100%) to carve the left-leaning trapezoid; the second gets the inverse polygon(60% 0, 100% 0, 100% 100%, 40% 100%). Because both panels occupy the same box, the diagonal seam is mathematically identical and never shows a hairline gap — no anti-aliasing artifact, no sub-pixel bleed. Text inside each panel uses normal flow with padding, so headings sit safely inside the visible polygon rather than fighting the diagonal edge. Two real gotchas: text in the clipped-away region is still selectable because clip-path only affects paint (not hit testing), so keep body copy padded well inside the visible area; and the panels need an explicit min-height on the wrapper or they collapse to zero and the whole component disappears silently. On mobile below 640px, swap the polygon to none and stack the panels vertically — diagonal seams produce awkward triangular slivers on narrow viewports. Baseline in Chrome 55+, Safari 14.1+, Firefox 54+ — safe for every tier-1 audience.
How do I build a before/after image comparison slider with pure CSS and one small JS handler?
Stack two panels in the same grid cell using grid-area: 1 / 1. The top panel gets clip-path: inset(0 calc(100% - var(--pos)) 0 0) so it's revealed only up to the --pos value. Overlay an <input type='range' value='50' min='0' max='100'> across the wrapper with position: absolute; inset: 0; opacity: 0, catching drag events across the whole surface. Under 20 lines of JavaScript listen for input and write e.target.parentElement.style.setProperty('--pos', e.target.value + '%'). A vertical handle uses left: var(--pos); transform: translateX(-50%) and pointer-events: none so drags pass through to the range beneath. Accessibility essentials: set step='5' on the range (default 1% requires 100 arrow-key presses to cross the panel), add aria-label describing what's being compared ("Before and after treatment"), and skip transitioning clip-path — cheap Android GPUs jank on clip-path animation. Baseline in Chrome 55+, Safari 9.1+, Firefox 54+. Real estate compare tools (Zillow, Redfin, Compass) and photo editing tutorials (Photoshop, Lightroom demos) use this exact pattern; average CPM $15-30 on real estate metros, $8-15 on tech-tutorial content.
How do I build a SaaS landing hero with split-screen sign-in like Stripe, Linear, Framer, Vercel, or Notion?
The canonical SaaS split hero is 55/45 in favor of the product visual, with the form panel on the trailing side. Structure: <section aria-label='Sign in'> as the outer landmark, then a display: grid; grid-template-columns: 55% 45%; min-height: 100vh wrapper. The visual panel paints its hero with a layered background-imageradial-gradient highlight over a linear-gradient base — so it ships without an image asset; brand copy floats bottom-left via align-self: end on the grid child. The form panel uses display: flex; flex-direction: column; gap: 1.25rem with inputs styled through :focus-visible rings at 3:1 contrast per WCAG 2.4.13. Include autocomplete='email' and autocomplete='current-password' attributes or password managers silently break. The social row uses display: grid; grid-template-columns: repeat(3, 1fr) for OAuth providers. Below 52rem the grid collapses and the product panel becomes a short banner — or hide it entirely with display: none under 36rem so the form is immediately actionable on phones. SaaS auth pages carry $8-25 CPM on Google Ads for developer keywords; the form-first mobile pattern lifts conversion 20-40% vs a full-height visual that pushes the form below the fold. This is the layout Stripe Checkout, Linear login, Framer sign-in, and Vercel dashboard auth all ship.
How do I build a real estate property comparison split screen like Zillow, Redfin, Compass, or Realtor.com?
The wrapper is a two-column grid using grid-template-columns: 1fr 1fr with a fixed viewport height, so each panel becomes an independent scroll container via overflow-y: auto. Each side holds a property card built from a stacked flex column: hero photo (16:10 aspect-ratio for consistent card height across property photos), price row, and a stats grid with beds, baths, and square footage rendered through grid-template-columns: repeat(3, 1fr). A center border-inline-start on the right panel provides the visual seam. Independent scroll containers mean aligned rows drift as users scroll one side — that's a feature, not a bug, because the point is direct comparison at each user's own pace. Highlight the winning field per row (lower price, more square footage) with a :has() selector on the stats grid, or precompute a data-winner attribute at build time. Add scroll-snap-type: y mandatory on each panel plus scroll-snap-align: start on stat rows so scrolling settles on comparable sections instead of arbitrary offsets. Real estate is a $15-30 CPM vertical on Google Ads (metro markets), $25-50 on tier-1 city luxury, and $30-60 on Manhattan / Bay Area / London prime. Fair Housing Act compliance (42 U.S.C. § 3604) requires that comparison tools don't steer users toward or away from properties based on protected characteristics — keep the fields you compare limited to objective property attributes (price, size, beds/baths), not location-neighborhood ratings that could function as proxies.
How do I build an editorial magazine split-screen spread with a headline that crosses both panels?
The spread uses grid-template-columns: 45% 55% in favor of the article text, with overflow: visible on both the wrapper AND the left panel so a centerpiece image can cross the boundary. The image is an absolutely positioned <img> inside the left panel with right: -20%; z-index: 2, pushing it into the right panel's territory. The headline is a separate absolutely positioned <h2> anchored to the grid wrapper with left: 30%; right: 10%, so it visually spans both panels while remaining a single semantic heading. Serif typography carries the editorial feel — font-family: 'Playfair Display', 'Fraunces', Georgia, serif with font-variation-settings: 'opsz' 72 if using a variable font. The left panel gets a muted tint (#f5f1ea); the right stays white. Because absolute positioning removes the headline from flow, add min-height on the wrapper or reserve space with an invisible spacer sized to the headline — otherwise the grid row collapses to panel content and the headline overlaps other elements. On narrow viewports below 640px, reset the image's right: 0 so it doesn't escape the card entirely. Vogue, Kinfolk, Cereal, The New York Times Magazine, and Substack Reads all use variations of this pattern; editorial content sits in the $5-12 CPM range but drives higher session depth (2-3× baseline) which compounds via display-refresh revenue.
How do I build a scroll-storytelling split with a sticky image and scrolling text like The New York Times or Pudding?
The wrapper is grid-template-columns: 55% 45% — text gets the larger column, sticky image the smaller. The left panel is a normal-flow stack of paragraphs (each ~3-6 paragraphs per chapter). The right panel is a grid cell with a single inner <div> using position: sticky; top: 0; height: 100vh. Because sticky is scoped to its nearest scroll ancestor, the image pins as the page scrolls until the right column's bottom edge passes the viewport top. The image itself uses object-fit: cover on an <img> so it never letterboxes. To swap images mid-story (the Pudding pattern), give each chapter its own image with staggered top offsets so each chapter's image pins for its own section — the effect reads as camera cuts synced to reading progress. Sticky silently fails when any ancestor has overflow: hidden, overflow: auto, or overflow: clip, so audit the ancestor chain before assuming the sticky rule itself is broken. The sticky child needs an explicit top value (top: 0 is standard) or it behaves like position: relative and never pins. On mobile, drop the sticky behavior entirely (or use a shorter height: 60vh) so the pin doesn't eat the whole small viewport. Long-form journalism using this pattern (NYT Snow Fall, Pudding data essays, Guardian long-reads) averages 8-12 minute session length — 4-6× baseline article dwell time.
How do I build a 3D perspective split screen with panels tilting into a virtual stage?
The stage is a wrapper with perspective: 1200px and transform-style: preserve-3d. Inside, two panels sit in a flex row: the left carries transform: rotateY(-6deg) and the right rotateY(6deg), plus transform-origin set to the inner edge so the tilt hinges toward the viewer. A CSS custom property --tilt drives both rotations (with opposite signs), and a small IntersectionObserver script toggles --tilt: 0deg when the card enters the viewport, easing the panels flat via transition: transform 700ms ease-out. On hover the tilt returns for a subtle re-engage. Critical detail: transform-style: preserve-3d must live on the parent, not the panels — setting it on the panels themselves leaves them flat because their own children would need the 3D context. Text inside tilted panels can look blurred on Windows Chromium due to subpixel rendering under 3D transforms; add will-change: transform during the animation and remove it after (the compositor promotes the layer for the duration only). Modern browsers can drop the JS entirely by using scroll-timeline with animation-timeline — Chrome 115+ and Edge 115+ support it natively; Safari and Firefox use the IntersectionObserver fallback. Under prefers-reduced-motion: reduce, skip the observer entirely and render both panels at --tilt: 0deg from first paint.
Do these CSS split-screen layouts work with React, Next.js App Router, Vue, Svelte, Astro, Tailwind, and shadcn?
Yes — every layout in this collection is framework-agnostic. The demos use CSS Grid, Flexbox, custom properties, :has(), clip-path, and (for a few) a small vanilla-JS handler for range-input sync or IntersectionObserver-driven tilt. None depend on a JavaScript framework's runtime, and none carry component library assumptions. To port into a React or Next.js App Router project, paste the HTML into a <section> component and drop the scoped CSS into a CSS module, styled-components, or a Tailwind @layer components block. The class prefixes (.ss-edt-, .ss-dia-, etc.) prevent global collisions when multiple split-screen sections appear on the same page. Tailwind v4 users can convert most rules 1:1 — grid-template-columns: 55% 45% becomes grid-cols-[55%_45%], clip-path: polygon(...) becomes an arbitrary variant. shadcn/ui doesn't ship a split-screen primitive (its Card and Sheet components serve different jobs), so these fill the ecosystem gap. Aceternity ($299/yr Pro) ships one split-screen hero at ~45KB with animation library dependencies; Magic UI and ReactBits similarly bundle motion libraries. The demos here ship at zero bundle cost — pure HTML + CSS + optional 20-line vanilla JS. Vue's <script setup>, Svelte's <script>, and Astro's <script is:client> all execute the same handler code without modification.

Related collections

15 CSS Aspect Ratio Demos preview

15 CSS Aspect Ratio Demos

15 hand-coded CSS aspect-ratio demos for video embeds, product galleries, IAB ad slots, native dialogs, and CLS-safe placeholders: 16:9 iframe YouTube embed with click-to-load facade + up-next rail, 21:9 full-screen hero video with min-height/max-height:100svh guardrails + Ken Burns drift, 1:1 Instagram-style square grid with 2×2 feature tile, 4:3 magazine card image cover, 9:16 vertical stories rail (TikTok/Reels/Shorts pattern) with scroll-snap + segment bars, 4:5 apparel product image gallery with radio-driven state + 1:1 thumbnails, 1:1 zoom thumbnail carousel with pointer-tracked --zx/--zy magnifier, prevent-layout-shift placeholder with live PerformanceObserver CLS meter (before/after side-by-side lab), dynamic content fallback with three policies (bend/strict/auto) via :has() toggle, IAB ad banner slots (728×90 leaderboard, 300×250 medium rectangle, 300×600 half-page, 320×50 mobile) with skeletons + container-query mobile swap, responsive modal dialog sized min(92vw, 88svh×16/9, 1080px) with @starting-style animation, responsive OpenStreetMap iframe wrapper with 16:9 → 1:1 container-query narrow swap, media query orientation live HUD + resize:both container-ratio playground, object-fit logo cloud with contain/cover/fill switcher via :has(), and side-by-side padding-top hack (height:0 + padding-top:56.25%) → modern aspect-ratio migration comparison with live ratio picker. 11 truly Pure CSS + 4 with a tiny optional vanilla JS snippet (facade swap, pointer magnifier, CLS meter, native dialog). Every demo is scoped under a unique .car-NN prefix so it drops into any project without CSS collisions, ships prefers-reduced-motion guards, and is framework-agnostic (works as-is in React, Vue, Svelte, Astro, Next.js, Remix, or plain HTML).

6 CSS Bento Grid Layouts preview

6 CSS Bento Grid Layouts

6 production CSS bento grid layouts with 12 hand-coded designs — Apple-style product showcase, SaaS feature value-prop matrix, analytics dashboard overview, creative portfolio, e-commerce category hub, and link-in-bio social hub. Each topic ships 2 sub-variants side-by-side so visitors see both a keynote aesthetic and a paper-doc variant at once. Container queries, CSS Grid, zero dependencies, copy-paste ready.

20 CSS Blog Layouts preview

20 CSS Blog Layouts

20 hand-coded CSS blog and editorial layouts for magazine homepages, news sites, personal archives, newsletter back-issues, recipe and podcast blogs, developer tutorials, and long-form journalism. Covers a magazine homepage with hero plus editor-picks rail, a news homepage with breaking-news ticker, blog archives with sticky year separators, Substack-style issue-numbered archives, recipe card grids with prep-time badges, podcast episode lists with waveforms, long-form articles with scroll-driven reading progress, drop caps and floated pull quotes via first-letter, Medium-style 65ch centred reader layouts, dev tutorials with a sticky code panel beside prose, interview transcripts with alternating speakers, case-study pages with stat counters, video blogs with an episode rail, full-bleed photo essays, news articles with sticky related-stories sidebars, documentation pages with prev/next chapter nav, a standalone blog post card, a scroll-snap category filter bar, an inline newsletter callout that breaks out of the prose column, and a horizontal featured-post rail. 12 are pure CSS with zero JavaScript. Every layout is scoped under a .bl-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

Search CodeFronts

Loading…