Skip to content
animorio
IT
All components

The reviews that roll

Carousels, Text, TransitionsGSAPMediumCompressed weight: Demo 6.0 KBGSAP + SplitText 31 KBFreeDownload the zip

One guest’s words at a time, in big letters, under quote marks in their colour: every few seconds the lines leave upwards one after another and the new ones rise into place a little tilted, the quote marks pop in the new colour, and under each guest a time bar fills while they speak.

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 reviews that roll</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/playfair-display@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/karla@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the reviews: one guest's words at a time, changing line by line, with the guests' tiles under them and a bar
         under each tile that fills while their review is showing -->
    <section class="reviews" role="region" aria-roledescription="carousel" aria-label="Guest reviews" data-reviews>
      <span class="reviews__mark" aria-hidden="true" data-mark>“</span>
      <div class="reviews__slides" aria-live="off" data-slides></div>
      <div class="reviews__foot">
        <div class="reviews__people" data-people></div>
        <div class="reviews__controls">
          <button class="ctl" type="button" aria-label="Previous review" data-prev>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14.5 6 8.5 12l6 6"/></svg>
          </button>
          <button class="ctl" type="button" aria-label="Next review" data-next>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9.5 6l6 6-6 6"/></svg>
          </button>
          <button class="ctl" type="button" aria-label="Pause the reviews" data-pause>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path class="ctl__pause" d="M9 6.5v11M15 6.5v11"/><path class="ctl__play" d="M8.5 6.2v11.6L18 12z"/></svg>
          </button>
        </div>
      </div>
    </section>
  </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/SplitText.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.

24 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 reviews that roll” from Animorio and fit it into my site

What it does

On a black background big peach quote marks and, under them, in a serif type, the words of Marta Silva: We stayed four nights and it felt like a week of Sundays. Breakfast under the fig tree, a room that smelled of lavender, and nobody in a hurry. Then her name and Lisbon, stayed in May. Further down five coloured tiles with initials (MS, JB, AT, LF, TW), the one speaking raised and lit, each with a thin bar under it, and on the right three round buttons: back, next, pause. The bar under the one speaking fills in six seconds; full, the lines leave upwards one after another behind their masks, the new ones rise a little tilted and straighten, the name and the place roll over, the quote marks pop in the new guest’s colour (blue, lavender, yellow, green) and their tile gives a hop; the bars before stay full, those after empty. With the pointer over it the bar stops, and so it does with pause, which turns into play. Next and back, the tiles, the arrow keys and a swiping finger change review; going back, the lines move downwards.

How it works

The lines behind their masks

Every review is a figure with the words, the name and the place; SplitText cuts them into lines, each in its own mask (mask lines). The review leaving sends its lines up by 108 per cent one after another (power2.in) and is then removed; the one coming lets its lines rise from 105 per cent below, turned by TILT degrees from their top left corner, STAGGER seconds apart, with expo.out.

Two reviews in the same place

The figures sit in the same cell of the grid (grid-area 1 / 1), so the one leaving and the one coming cross in the same place; the box keeps the height of the longest review (all measured once, invisible, at the start and when the width changes), so nothing under it jumps.

The colour and the quote marks

The colour is a CSS variable (--tone) that GSAP takes from one guest’s colour to the next; the quote marks pop with elastic.out from 0.55 and −16 degrees, round a point low on the left of the mark (they are as wide as themselves, fit-content).

The time bars

The bar of the review showing is a scaleX from 0 to 1 in SHOW seconds, with no ease; at its end the next review comes. The pointer over it (a mouse), the keys inside it (focus-visible) or the pause button stop it; stopped, the box is aria-live polite, moving it is off.

Keys and fingers

It is a region with aria-roledescription carousel; the tiles are buttons with aria-current, the arrow keys change review and a finger swiping sideways on the words (touch-action pan-y) goes to the next or the previous one. With reduced motion the reviews wait for the play button.

Values to change

NameFileDefaultWhat it changes
SHOWscript.js6The seconds a review stays before the next one comes.
STAGGERscript.js0.07The seconds between one line and the next as they rise in.
TILTscript.js4How tilted a line is as it starts rising, in degrees.
REVIEWSscript.js[{ name: 'Marta Silva', when: 'Lisbon, stayed in May', tone: '#f2a98a', words: '…' }, …]The reviews: name, where from and when, colour, words.

Try them in the Playground

When to use it

For a guesthouse’s reviews, customers’ testimonials, quotes from the press, comments on a product: where a few sentences well said are worth more than a list.

On phones

The words shrink down to 22 pixels, the tiles and the buttons go underneath, on two rows; a finger swipes sideways on the words to change review.

With reduced motion

The reviews do not move by themselves, they wait for the play button; changing, the words swap without lines rising, the quote marks change colour without popping and the tiles rise without a hop.

Pitfalls

  • The lines depend on the type: cut before the font has loaded, they come out wrong. Here the first review waits for document.fonts.ready, and at every change of width the lines are cut again.
  • Reviews of different lengths would make everything under them jump: the box takes the height of the longest one, measured once.
  • A block element as wide as the column turns and scales round a point far from its drawing: the quote marks are as wide as themselves (fit-content), or their pop would pass over the text.
  • A carousel that moves by itself must be possible to stop (WCAG 2.2.2): the pause button, the pointer over it and the keys inside it stop it, and stopped, new reviews are read aloud.

Libraries

GSAP 3.15.0, SplitText (GSAP) 3.15.0, Playfair Display (font variabile) 5.3.0, Karla (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 6.0 KB; the libraries: GSAP + SplitText 31 KB.

Testing

Tested on 3 October 2026

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

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 components