Skip to content
animorio
IT
Back to the library

The split-line transition

Transitions, TextGSAP, CSS onlyMediumCompressed weight: Demo 7.4 KBGSAP 28 KBFreeDownload the zip

A minimal click page change: a thin line cuts the page in half, the two halves open up and down like a drawer and the new page widens out of the gap, its title running in along the line. Going back the halves slide shut with a little knock and the line closes like a seam.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The split-line transition</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the first page: the headline sits right across the line, so the cut runs through its letters -->
    <section class="page page--a is-on" data-page="a" aria-label="Objects">
      <header class="bar">
        <span class="brand">Halden</span>
        <nav class="nav" aria-label="Pages">
          <a href="#objects" aria-current="page">Objects</a>
          <a href="#studio" data-go="b">Studio</a>
        </nav>
      </header>
      <div class="hero hero--a" data-hero-a>
        <p class="kicker">Spring collection</p>
        <h1 class="headline" data-headline>Made slowly.</h1>
        <a class="go go--next" href="#studio" data-go="b" data-autoclic>
          <span class="go__text">Visit the studio</span>
          <span class="go__arrow" aria-hidden="true"><span class="go__shaft"></span><svg class="go__head" viewBox="0 0 8 12"><path d="M1.5 1.5 6.5 6l-5 4.5"/></svg></span>
        </a>
      </div>
      <footer class="foot">
        <span>Ceramics and furniture</span>
        <span>Since 2009</span>
      </footer>
    </section>

    <!-- the second page: its title stands on the line -->
    <section class="page page--b" data-page="b" aria-label="Studio" aria-hidden="true">
      <header class="bar" data-b-top>
        <span class="brand">Halden</span>
        <nav class="nav" aria-label="Pages">
          <a href="#objects" data-go="a">Objects</a>
          <a href="#studio" aria-current="page">Studio</a>
        </nav>
      </header>
      <div class="hero hero--b">
        <h2 class="title" data-title>The studio</h2>
        <div class="below" data-below>
          <p class="lede" data-rise>Six people, one kiln and a long oak table. We make a few things each year, and mend them for life.</p>
          <a class="go go--back" href="#objects" data-go="a" data-autoclic data-rise>
            <span class="go__arrow" aria-hidden="true"><svg class="go__head" viewBox="0 0 8 12"><path d="M6.5 1.5 1.5 6l5 4.5"/></svg><span class="go__shaft"></span></span>
            <span class="go__text">Back to objects</span>
          </a>
        </div>
      </div>
      <footer class="foot" data-b-foot>
        <span>Open by appointment</span>
        <span>Since 2009</span>
      </footer>
    </section>

    <!-- the two halves of the page being cut, and the line itself (both built and moved by the script) -->
    <div class="halves" data-halves aria-hidden="true"></div>
    <div class="cut" data-cut aria-hidden="true"></div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

30 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The split-line transition” from Animorio and fit it into my site

What it does

The site of a made-up ceramics and furniture studio, Halden, in two pages and almost nothing else: a paper-coloured background, one huge headline, a line of text, a terracotta line. On load the line crosses the screen from the middle to the edges and the two halves of the first page come in from above and below, shut on the line with a little knock and a bounce of a few pixels; the line stays a moment as a seam, then draws back into the middle. The headline, Made slowly., sits right across the cut. A click on Visit the studio starts the line from the point you clicked and runs it out to both edges; the page cracks open a few pixels, waits a breath, then the two halves slide away, one up and one down, cutting the headline's letters. Out of the gap widens the dark page: its header comes down and its footer comes up from the middle into place, and the new title, The studio, runs in along the line from the left, leaning and condensed while it moves, the letters bunching up and widening as it stops. Then the line shrinks to the width of the title and stays under it, and the text and the link back rise one after the other. A click on Back to objects sends the title off along the line to the right, last letter first, the halves of the first page slide shut over the dark page, knock and settle, and the line closes into the middle.

How it works

Two cut copies

The real pages are never cut. The script makes two copies of the page that is leaving, lays them one on the other exactly in its place and clips them with clip-path: inset(0 0 calc(100% - var(--cut)) 0) for the top copy, inset(var(--cut) 0 0 0) for the bottom one. The clip moves with the copy, so moving the two copies in y is enough. In the copies data-go and data-autoclic are removed and the links leave the Tab order, so nobody clicks them.

The line from the click

The line is a div one pixel tall, as wide as the page, with transform-origin on the left. Its position is written as a left end (x) and a length (scaleX): starting from the click means x at the click point and scaleX zero, and reaching the edges means x zero and scaleX one. With the same easing both ends arrive together even when one side is longer. The same trick shrinks it under the title and closes it into the middle.

The drawer

First a crack of a few pixels with power3.out, then a moment still, then the halves run to the edges with power4.inOut: the pause between the two pushes is what makes it feel like a drawer. When shutting, the halves come in with power3.in (speeding up into the knock), bounce back KNOCK pixels in 0.09 seconds and settle with elastic.out(1, 0.4). The new page waits underneath, while its header and footer open out from the middle with expo.out, a little behind the halves.

The title along the line

The title is split into letters, each an inline-block whose font-stretch is tied to the --w variable (Instrument Sans runs from 75 to 100 in width). Each letter starts pushed left by nearly a letter height plus TRAIL for every letter ahead of it: arriving with expo.out the gaps close and the letters bunch up like carriages braking. The lean springs back to zero with an elastic, and --w widens to 100 starting from the last letter. The title's baseline is measured with an empty element sitting on the baseline, so it stands exactly on the line.

Direction, phone and reduced motion

Each change is one timeline with the labels draw, crack, open, title, settle (and leave, run, shut, knock on the way back) and timeScale for SPEED. A click that comes while the page is changing waits in a queue. The measures are taken again on every resize: both big lines fit the width, the cut sits at LINE_AT of the height. With reduced motion the line fades in, the pages swap with a fade and the title appears already in place.

Values to change

NameFileDefaultWhat it changes
LINE_ATscript.js0.5Where the cut runs, from the top: 0.5 is right in the middle, 0.35 higher, 0.65 lower.
DRAWscript.js0.6The seconds the line takes to cross the page.
OPENscript.js1.05The seconds the two halves take to open (and, a little faster, to shut).
CRACKscript.js6How many pixels the page cracks open before it slides: 0 = the halves go at once.
KNOCKscript.js5How many pixels the halves bounce back when they shut: 0 = they just stop.
TRAILscript.js0.32How strung out the title's letters arrive along the line, in letter heights: 0 = all together.
SPEEDscript.js1The speed of everything: 2 is twice as fast, 0.5 half as fast.

Try them in the Playground

When to use it

To move from one page to another on a quiet site where the type does all the work: a designer's or an architect's studio, a furniture or ceramics brand, a portfolio, an agency's about page, the step from the home page to a section. It works well with a light and a dark background taking turns.

On phones

The same transition with the sizes adapted: both titles shrink to fit the width of the screen, the cut stays halfway down and the text wraps under the line. A tap on the link opens it and shuts it again.

With reduced motion

Nothing moves: the line fades in, the first page fades out as the second fades in with its title already in place, then the text; going back the first page fades back in and the line disappears.

Pitfalls

  • With a shadow under each half's edge, the bottom half (drawn on top) cast its shadow over the top half, and once shut a grey band stayed across the headline: the shadows are gone, the depth comes from the new page opening out of the middle.
  • The copies of the page carried data-autoclic with them: the autopilot counts every marked element and clicked the copies. data-autoclic and data-go are removed from the copies.
  • The letters are inline-blocks so they can move, and as font-stretch changes they change width and push their neighbours: the title's width and the line's ends are measured with the letters still, --w at 100, before they are hidden.
  • A click that comes halfway through the change (the previews' autopilot clicks every 2.8 seconds) would start on top of a timeline still running: it waits in a queue and goes as soon as the timeline ends.
  • The autopilot's click (el.click()) has no coordinates: then the line starts from the middle of the link, not from zero.

Libraries

GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 7.4 KB; the libraries: GSAP 28 KB.

Testing

Tested on 14 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All animations