Skip to content
animorio
IT
Back to the library

The cards that straighten up

Scroll, TextGSAP, CSS onlyEasyCompressed weight: Demo 3.7 KBGSAP + ScrollTrigger 45 KBLenis 5.3 KBFreeDownload the zip

Scroll inside the preview

A studio’s services on three overlapping cards, in the minimal style: each card comes up crooked and pushed to one side, the next one to the other, and straightens as it reaches the top, tied to the scroll. The title follows it: thin round dots while it is crooked, solid square pixels once it is straight.

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 cards that straighten up</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bitcount-prop-single@5.3.0/full.css">
  <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>
  <!-- the services of a made-up games studio, Pixmoor, on three overlapping cards. Each card comes up tilted and
       off to one side, the next one the other way, and straightens as it reaches the top of the screen; its title
       turns from thin round dots into solid square pixels as it does. Leaving, the card tips over the other way -->
  <main class="pagina">
    <header class="apertura">
      <p class="occhiello">Pixmoor, what we make</p>
      <h1 class="apertura__titolo">Three things, done properly.</h1>
      <p class="scendi">Scroll</p>
    </header>

    <section class="mazzo" aria-label="Services">
      <article class="carta carta--chiara" data-carta>
        <div class="carta__dentro" data-dentro>
          <h2 class="carta__titolo" data-titolo>Level design</h2>
          <ul class="carta__voci">
            <li>Worlds</li>
            <li>Puzzles</li>
            <li>Pacing</li>
          </ul>
          <p class="carta__testo">Maps that teach without a tutorial, and a last room people talk about.</p>
        </div>
      </article>

      <article class="carta carta--scura" data-carta>
        <div class="carta__dentro" data-dentro>
          <h2 class="carta__titolo" data-titolo>Characters</h2>
          <ul class="carta__voci">
            <li>Sprites</li>
            <li>Animation</li>
            <li>Voices</li>
          </ul>
          <p class="carta__testo">Heroes with a walk you would know from across the screen.</p>
        </div>
      </article>

      <article class="carta carta--accento" data-carta>
        <div class="carta__dentro" data-dentro>
          <h2 class="carta__titolo" data-titolo>Trailers</h2>
          <ul class="carta__voci">
            <li>Teasers</li>
            <li>Launch</li>
            <li>Store pages</li>
          </ul>
          <p class="carta__testo">Ninety seconds that sell the feeling of the first hour.</p>
        </div>
      </article>
    </section>

    <footer class="chiusura">
      <p class="chiusura__titolo">Got a game?</p>
    </footer>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.

32 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 cards that straighten up” from Animorio and fit it into my site

What it does

Pixmoor, a made-up games studio, presents three services on three cards: a light one, a black one and a violet one, overlapping a little. As you scroll, each card comes in from the bottom of the screen tilted by eight degrees and pushed a tenth of its width to the side, the first to the left, the second to the right, the third to the left again, and straightens as it rises, until it is straight when its top edge reaches a fifth of the way down the screen. The title follows: while the card is crooked it is made of thin rings, and once it is straight the dots have become solid square pixels. Then, as the next card covers it, the inside of the one below tips over the other way and slides off.

How it works

Coming in

Each card has a timeline tied to the scroll with scrub, from when its top edge comes in at the bottom of the screen to when it reaches SETTLE: it starts from rotate TILT and xPercent SHIFT, with the sign changing from one card to the next, and goes back to zero with power1.out, so it straightens early and settles slowly.

Going out

A second timeline runs from SETTLE to when the card leaves at the top: it tips the inside of the card the other way and pushes it further to the side, with power1.in, so it starts slowly and speeds up. The two timelines move two different elements, the card and its inside, so they never fight over the transform.

The title

The title has two CSS properties, --forma and --peso, that feed font-variation-settings (Bitcount’s ELSH axis) and font-weight. The same timelines take them from ROUND and LIGHT to 50 and 700 on the way in and back on the way out; on the way out the tween is a fromTo with immediateRender: false, so the starting point is always the right one.

The phone and the scroll

With gsap.matchMedia, on a phone the tilt and the shift are halved. Lenis makes the scroll soft and short, SMOOTH seconds on a braking curve, as on the site.

Values to change

NameFileDefaultWhat it changes
TILTscript.js8How tilted a card is coming in and going out, in degrees (half on a phone).
SHIFTscript.js10How far it is pushed to the side, as a percentage of its width (half on a phone).
SETTLEscript.js'top 20%'Where the card is straight: when its top edge reaches this point of the screen.
LIGHTscript.js300The weight of the title while the card is crooked; straight it is 700.
ROUNDscript.js0The shape of the title’s dots while the card is crooked: 0 round, 50 square.
SMOOTHscript.js0.5The seconds of the smooth scroll; 0 for the browser’s own.

Try them in the Playground

When to use it

For the services of a studio or an agency, the plans of an app, the sections of a landing page: three or four large cards, one after the other.

On phones

The same, with the tilt and the shift halved and the card’s text under the tags.

With reduced motion

The cards stay straight and still and the title is already in square pixels; the scroll is not smoothed.

Pitfalls

  • gsap.matchMedia only calls the function if at least one condition is true: with only the phone and reduced motion conditions, nothing starts on a computer. The wide screen condition is needed too.
  • Coming in and going out on the same card would fight over the transform: coming in moves the card, going out moves its inside.
  • The title’s exit tween must be a fromTo with immediateRender: false; with a to it would record as its start the values of the first time it plays, maybe halfway in after a jump of the scroll.
  • The light card’s thin outline is an inset box-shadow: with a real border the cards would have different sizes and the overlap would not line up.

Libraries

GSAP 3.15.0, Lenis 1.3.26, Bitcount Prop Single (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 3.7 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB.

Testing

Tested on 17 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