055

Split Screen Template

£20 or the whole Vault, £99

A one-page site for an independent industrial design studio, built as two committed full-height fields — an ochre one and a near-black one — divided by a seam the visitor can actually drag. Scroll sends the two fields in opposite directions, the headline straddling the divide is knocked out correctly on both grounds, project plates are dealt out from the seam in a pinned sequence, and a second seam further down bends toward the cursor.

ScrollTriggerDraggable Lenis intermediate
13 more details
draggableparallaxpinningscrubscroll-revealstaggerclip-pathmouse-followpointer-effectsquickTotoken-themingprogressive-enhancementkeyboard-navigation

This template reads better at your own screen size than in the frame below:

Updated

About this template

A production-ready one-page site for an independent industrial design studio, shipped as a finished site for a fictional six-person practice, KERF, working out of a converted cutlery works in Sheffield. Real project entries, real capabilities, a real address block: what you open reads as a working studio rather than a grid of placeholder headings.

Read the full template overview

The whole page is two fields and the line between them. An ochre field and a warm near-black field each hold a full viewport height, and there is no third surface anywhere on the site — no neutral page, no cards floating on a background. Scrolling the hero sends the two fields travelling in opposite directions, and the seam between them is a real control: drag it and one field takes the width off the other, with the display headline that straddles it staying legible on both grounds because it is painted twice and clipped to either side of the divide.

Two more interactions carry the rest of the page. A pinned sequence deals the project plates out of a vertical seam line, edge-on at first, then fanned to alternating sides as the pin scrubs. Further down, a second seam bends toward the cursor on a fine pointer, with the heading's tracking and the ochre hatch reacting to the same input; a touch device gets a machined, notched, straight line instead.

Make it yours by repainting five values in the token block at the top of the stylesheet and swapping the five photographs in assets/img. Every section is found by a data attribute and separately guarded, so you can delete the pinned work stage, the capabilities index or the workshop split and the rest keeps running.

Split Screen Template - website template preview

What's included

11 items
  • Two committed full-height fields, ochre and near-black, with no third surface anywhere on the page
  • A draggable seam that re-weights the two halves, carries on to a near full-bleed extreme when you throw it, and settles back to level with an eased overshoot rather than a snap
  • A display headline straddling the seam, painted twice and clipped to either side of it, so it reads correctly on ochre and on near-black and the knockout follows the handle
  • Counter-scrolling fields: the ochre side rises and the near-black side falls as the hero leaves, with the photographs given more travel than the copy beside them
  • Three project plates dealt out of a vertical seam line in a pinned, scrubbed sequence, budgeted at more than a viewport of travel per plate so one hard flick cannot clear the lot
  • A second seam that bends toward the cursor across five nodes, widening the heading's tracking and lifting the ochre hatch off the same pointer input
  • A ruled capabilities index whose numbers hang outside the text column, set against the sparse studio statement above it
  • An oversized ghost numeral and a contact address deliberately run past the edges of the page
  • Bundled, optimised WebP photography, every frame baked to monochrome so ochre stays the only colour on the site, with per-image brightness matched to the ground it lands on
  • Every measured contrast ratio written into the stylesheet header, including which colour is banned as text on which field and why
  • Accessible throughout: a complete static document with no JavaScript, a designed reduced-motion page with the plates back in a plain index, a keyboard-operable seam slider, and a blocked CDN that degrades to the plain document

Perfect for

6 use cases
  • Industrial, product and furniture design studios presenting their own practice
  • Engineering, prototyping and small-batch manufacturing businesses
  • Architecture and interiors practices that want a hard, two-colour identity rather than a neutral page
  • Any studio whose work is best shown as a small number of substantial projects rather than a large grid
  • Design and fabrication consultancies that want a site with one memorable interaction rather than a carousel
  • A starting point for any two-tone brand, since the whole palette is five values in one token block

How it works

6 sections

Structure

One script initialises every section with a single setup and teardown path, and one motion branch whose conditions cover coarse pointers and narrow viewports as well as desktop, so exactly one branch runs on every device. Each block is found by a data attribute and returns early if it is absent, so deleting any section leaves the others working. Teardown is exposed on window and reverts the whole context, because killing the tweens alone would leave the responsive branch's own cleanup unrun.

The draggable seam

One CSS custom property, --seam-x, is the single source of truth for the split. The ochre field's width, the masthead's paint stop, both clipped copies of the headline and the reflow width of each field note all read it, so moving the handle re-cuts the whole composition instead of sliding a divider across it. Draggable drives a detached proxy element rather than the seam itself, which keeps the divider from having two sources of truth. Two more channels come off the same drag: the headline's tracking tightens as the ochre field loses ground, and the hatch on the ochre field strengthens as it gains. Released past thirty or seventy per cent, the seam carries the rest of the way to a near full-bleed extreme on a long expo run-out; released nearer the middle, it settles back to level with a small overshoot.

The straddling headline

The headline is drawn three times: once for assistive technology in a visually hidden span, then twice on screen. One painted copy is near-black and clipped to everything left of the seam, the other is bone and clipped to everything right of it, both against the same --seam-x. That is why the type stays legible whichever ground it lands on, and why the knockout follows the handle without any per-frame work. Below 820px the same two copies clip horizontally instead, against the join between the stacked fields.

Plates dealt from the seam

The work section pins and scrubs. Each project plate starts flattened edge-on against the vertical rail, opens out, and is thrown to its side with a little rotation, the way a card leaves a dealer's hand. The pin is budgeted at more than a full viewport of travel per plate, so a single hard scroll flick cannot clear the sequence and land past it with the deck already built. Without JavaScript, and under reduced motion, the same plates render as a plain three-up index in ordinary document flow.

The bending seam

The second split is divided by a five-node clip-path polygon whose nodes are CSS variables. On a fine pointer, each node is pulled sideways by a bell curve centred on the cursor's height, so the bend is strongest beside the pointer and eases away above and below it; the whole thing is smoothed and written once per frame. The same pointer position widens the heading's letter-spacing and lifts the ochre hatch. On a coarse pointer none of it runs and the seam holds a straight, notched, machined edge, which is a designed state rather than a switched-off one.

Without JavaScript

The gating class goes on in the head before first paint, so reveal start states apply to the first frame and nothing is painted visible and then hidden; the script removes that class when GSAP is missing, so a blocked CDN degrades to the plain document. With scripting off the seam sits at the halfway mark, the headline still reads correctly on both fields because the clipping is pure CSS, the work plates render as a three-up index and the second seam is straight and notched. Under reduced motion the seam stays operable from the keyboard, it just moves in one step instead of easing.

Plugins ScrollTrigger, Draggable
Difficulty Intermediate
Smooth scroll Lenis integration
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this template's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Questions about this template

Can visitors really drag the divide?

Yes. The seam re-weights the two halves, carries on to a near full-bleed extreme if you throw it, and settles back to level with an eased overshoot rather than snapping. It is keyboard-operable as a slider too, so it is not a pointer-only flourish.

How does the headline stay readable across two grounds?

It is painted twice and clipped to either side of the seam, so it reads correctly on ochre and on near-black, and the knockout follows the handle as you drag. The stylesheet header records which colour is banned as text on which field and why.

Do my photographs need to be monochrome?

Effectively yes. Every bundled frame is baked to monochrome so ochre stays the only colour on the site, with per-image brightness matched to the ground it lands on. Dropping in colour photography breaks the two-colour idea that is the whole template.

Is it only for industrial design?

No. Engineering, prototyping, small-batch manufacturing, architecture and interiors all suit the hard two-tone identity. What it needs is a small number of substantial projects rather than a large grid: three project plates are dealt from the seam, and that count is the shape of it.

Can one fast scroll flick past the whole project sequence?

No. The plates are budgeted at more than a viewport of travel each in the pinned scrubbed sequence, so a single hard flick cannot clear the lot. Under reduced motion the plates fall back to a plain index.

Paid template

Purchase to unlock the code.

Buying Split Screen Template opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£20 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

  1. Upload the whole folder to any static host (Netlify, Vercel, Cloudflare Pages, S3, a plain Apache directory). index.html is the site.
  2. Replace the fictional studio: search index.html for KERF, the address on Cornish Street, the phone number and studio@kerf.works.
  3. Replace the photographs by dropping your own files over the five in assets/img/ (see Photography).
  4. Repaint the palette: five values at the top of assets/style.css (see Palette).

Open it locally over file:// if you like, but serve it over HTTP (npx serve, python3 -m http.server) before judging the scroll: pinning and smooth scroll both behave differently from a file URL.

What loads

Code snippet omitted: it ships with the download.

Everything is optional except gsap.min.js and ScrollTrigger.min.js. Drop Draggable.min.js and the seam becomes a keyboard-only slider. Drop Lenis and the page uses native scrolling; nothing else changes.

assets/script.min.js is the minified build of assets/script.js. Point the last tag at whichever you prefer; edit the unminified one.


The sections, and what you can change

Every section is found by a data- attribute and separately guarded, so you can delete any of them from index.html and the rest keeps working. Nothing is paired by index.

Hero — [data-hero] [data-split]

The two fields, the counter-scroll and the draggable seam.

To change Where
How far the seam can travel MIN_PCT / MAX_PCT in script.js (0.15 / 0.85)
How far a throw has to go before it carries to an extreme EDGE_LO / EDGE_HI (0.30 / 0.70)
The settle the two moveTo(…) calls in settle(): expo.out out to an edge, back.out(1.25) back to level
Keyboard step size stepPx in the keydown handler (4% of the width per press)
How much the two fields disagree while scrolling the yPercent values in initCounterScroll (-13 and 11, photos -18 and 16)
How hard the tracking and the hatch react to the drag the two root.style.setProperty lines in apply()
The headline the two .hero-title-layer spans — edit both, and the .sr-only copy above them

The headline is deliberately painted twice. One copy is near-black and clipped to everything left of the seam, the other is bone and clipped to everything right of it, both against the same --seam-x. That is what keeps it legible on either ground, and it is pure CSS, so it still works with JavaScript off.

Studio statement — [data-brief]

An oversized ghost numeral running off the left edge with one narrow column set against it. The numeral is .brief-ghost; it is aria-hidden and sized in vw, so it stays proportionate at any width. Its string lives on the element's data-mark attribute and is drawn by .brief-ghost::before { content: attr(data-mark); }, so the numeral is generated content rather than text a screen reader or a contrast audit has to skip. To change it, edit data-mark, not the element.

Work — [data-work]

A pinned stage that deals the plates out of the seam. Add or remove <li class="plate" data-plate> entries freely; the pin length is computed from how many there are.

To change Where
Pin length TRAVEL_PER_PLATE in initWork (1.15 viewports per plate)
Which side a plate is dealt to data-side="left" / "right" on the <li>
How far they fan the x: function in the second tl.to (26% of the width, capped at 340px)
The rail .work-rail in style.css

Keep TRAVEL_PER_PLATE at or above 1: with less than a viewport of travel per plate, one hard scroll flick clears the whole sequence and lands past the section with the deck already built, which reads as the page leaping.

Capabilities — [data-index]

A ruled index with the numbers hanging outside the text column. Pure CSS apart from the shared scroll reveal; add or remove <li> rows freely.

Workshop — [data-workshop]

The second split, with a seam that bends toward the cursor.

To change Where
How far the seam bends REACH in script.js (0.34 of the width)
How far up and down the bend carries SPREAD (0.15 — smaller is a sharper kink)
How many nodes the divider has NODES, and the matching --b0…--b4 in the .ws-field--ochre polygon
How quickly it follows the duration in the quickTo setters
The static touch state .ws-notches in style.css

Contact and footer — [data-contact]

The address line is set larger than anything else on the page and runs past the right edge on purpose; .contact has overflow: hidden to contain it.


Palette

The whole site is five colours. Repaint these in :root at the top of assets/style.css — each hex in step with its -rgb triple — and the site is yours:

Code snippet omitted: it ships with the download.

Every translucent value on the page — hairlines, dimmed copy, the hatch — resolves from one of those -rgb triples rather than a hardcoded rgba(…) literal, which is the only reason a repaint is a five-value edit instead of a hunt through the stylesheet.

Re-measure before you ship a repaint. The stylesheet header records every pair as it is actually used, and two of them have no headroom:

  • Ink on ochre is 5.67:1, and the dimmed variant --on-ochre-dim (ink at 0.85) is 4.63:1. That is the AA floor for body copy. Lightening --ochre much past #C77B2E, or dimming ink further, drops the studio statement and the capabilities index below it.
  • Bone on ochre is 2.86:1 and is therefore banned as text on the ochre field at every size. The ochre field always takes near-black ink; the near-black field always takes bone. Nothing crosses. If you invert the two grounds, swap the type roles with them.
  • --ochre-deep carries rules, hatching and the decorative numeral only. Ink on it is 4.02:1, which clears the 3:1 floor for display type but not the 4.5:1 body floor, so no paragraph is ever set on it.

Type roles are stated per ground (--on-ochre, --on-ochre-dim, --on-ink, --on-ink-dim, --on-ink-faint) so it is difficult to use the wrong one by accident.

Type

Syncopate for display, Urbanist for everything you read, both from Google Fonts in index.html. Syncopate is wide-tracked caps and is only ever used at heading sizes and above; it is unreadable as body copy, so if you swap it, swap it for another display face and leave --font-body doing the reading.

At 1440px the headline is 96px against 15.2px body copy, a ratio of about 6.3 to

  1. That ratio is where the tension in the page comes from. Shrinking the headline is the fastest way to make this template look ordinary.

Photography

The five images in assets/img/ are bundled, optimised WebP derivatives, not redistributed originals. Each one is baked to full monochrome so ochre stays the only colour on the site, with brightness set per image and matched on perceived brightness against the ground it lands on: the dark parts pile is lifted so it separates from the ochre field, the bright machining shot is pulled back so it does not blow out against the near-black one.

File Size Where it sits
split-left.webp 1200×1500 the ochre hero field
split-right.webp 1200×1013 the near-black hero field
plate-01…03.webp 900px square-ish the plates dealt from the seam

To swap them: replace the files in assets/img/ keeping the same names. Every slot uses object-fit: cover against a fixed aspect ratio, so your files do not have to match these dimensions and no numbers need changing. Update the width/height attributes and the alt text in index.html to match what you actually shipped. Every photo also sits on a background-color fallback, so the page looks designed before the images arrive.

To re-bake with a different grade: assets/img-manifest.json holds the source for each image plus its output size, quality and grade. Edit the src values or the grade block and run:

Code snippet omitted: it ships with the download.

If you drop the monochrome grade, expect the page to change character: a colour photograph in the ochre field competes with the field, and a colour photograph on the near-black field floats off it.

Photo credits

The originals are royalty-free photographs from Unsplash. What ships in assets/img/ are altered, graded derivatives, not the originals; these are the source files each one was baked from, and re-running the manifest fetches them again.


Accessibility

  • Without JavaScript the page is a complete, readable document. The seam sits at the halfway mark, the headline still reads correctly on both fields because the clipping is pure CSS, the work plates render as a plain three-up index, and the second seam is a straight, notched line. If the GSAP CDN is blocked, script.js removes the has-js class so nothing stays hidden behind an animation that will never run.
  • Reduced motion gets a designed static page rather than the animated one switched off: the fields hold level, the plates return to the three-up index in ordinary flow, the second seam is straight, and every reveal is simply visible. The seam slider stays operable from the keyboard — it moves in one step instead of easing.
  • The seam is keyboard-operable. The handle is a focusable role="slider" with an aria-label, a live aria-valuenow and a spoken aria-valuetext. Left and right arrows move it in 4% steps, Home and End go to the two extremes, PageUp/PageDown step just inside them.
  • Touch. The bending seam is a fine-pointer interaction; a coarse pointer gets the notched straight edge instead. Below 820px the split turns vertical — ochre above, near-black below, the headline straddling the join and clipped horizontally — and the drag handle steps aside. The two committed fields, which are the identity of the page, survive intact.
  • Skip link, visible focus rings (recoloured per ground so they are never bone on ochre), one <h1>, sequential headings, real <nav>/<main>/<footer> landmarks, and alt text on every photograph. Decorative type — the ghost numeral, the wordmark's slash, both painted copies of the headline — is aria-hidden, with the headline's accessible copy in a visually hidden span. The ghost numeral goes further and is not text at all: its string sits on data-mark and is painted as CSS generated content.

Teardown

Every animation lives in one gsap.context. To pull the page apart in a single-page app, call:

Code snippet omitted: it ships with the download.

revert(), not kill(): kill() leaves matchMedia's own cleanup unrun, which strands inline transforms on the page.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.