Skip to content
animorio
IT
All components

The star rating

Ratings, SVG, HoverGSAPMediumCompressed weight: Demo 5.7 KBGSAP 28 KBFreeDownload the zip

Five stars to answer a question: the gold fills them like a liquid running after the pointer, its edge rippling as it moves; once picked, the stars spin into place one after the other, a glint crosses them and the word underneath changes.

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 star rating</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the rating: five stars over five real radio buttons. The gold fills them like a liquid that runs after the
         pointer, its edge rippling while it moves; picked, the stars spin into place one after the other, a glint
         runs across them and the word under them changes. The stars are drawn by the script -->
    <form class="rate" data-rate onsubmit="return false">
      <p class="rate__ask" id="rate-ask">How was your stay?</p>
      <fieldset class="rate__stars" aria-labelledby="rate-ask" data-stars data-autoclic>
        <svg class="rate__art" aria-hidden="true" data-art>
          <defs>
            <linearGradient id="gold" x1="0" y1="0" x2="0" y2="1" data-gold>
              <stop offset="0" stop-color="#ffc83d"/>
              <stop offset="1" stop-color="#ff9a1f"/>
            </linearGradient>
            <clipPath id="level"><path data-level/></clipPath>
            <clipPath id="glint-clip"><path data-glint-clip/></clipPath>
          </defs>
          <g class="rate__empty" data-empty></g>
          <g class="rate__full" clip-path="url(#level)" data-full></g>
          <g clip-path="url(#glint-clip)"><rect class="rate__glint" data-glint/></g>
        </svg>
        <div class="rate__choices" data-choices></div>
      </fieldset>
      <p class="rate__word" aria-hidden="true"><span data-word>Tap a star</span></p>
      <p class="rate__thanks" role="status" aria-live="polite" data-thanks></p>
    </form>
  </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.

16 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 star rating” from Animorio and fit it into my site

What it does

On a white background the question How was your stay?, five empty stars with a pale outline and, below, in grey italics, Tap a star. When the page opens the stars pop up spinning, one after the other. Moving the pointer over them, the gold fills them up to the star pointed at like a liquid: it runs on a spring, its edge ripples as it moves and lies straight when it stops, in the gap between two stars; the star under the pointer grows, its neighbours a little, and below reads the word for that number: Terrible, Not great, Okay, Good, Wonderful. Leaving, the gold goes back to the choice made. On a pick, the stars taken spin into place one after the other, the last with a jolt, a white glint runs over the gold and below appears Thanks, that helps other guests.; with one or two stars the gold turns redder. A finger can slide along the stars, and the choice falls where it lifts.

How it works

Stars over real radio buttons

Under the stars there are five see-through radio inputs, one over each star: the keyboard (the arrows change the choice), screen readers and forms work as always, and a click on a star is a click on its radio. The stars are an SVG the script draws: five empty ones and, over them, five gold ones.

The liquid

The gold stars are cut by a clipPath reaching up to the level: it crosses a star and jumps the gap to the next. The level goes towards the number pointed at on a spring (SPRING), worked out on GSAP’s ticker in steps of 4 milliseconds, and the cut’s edge ripples by WAVE pixels times its speed: still, it is straight.

The star that grows

The star under the pointer goes to 1.16 times its size and its neighbours to 1.05, with elastic.out, round their own middle (transformOrigin set through GSAP, which works it out on each star’s box for SVG). Leaving, they go back to 1 and the level goes back to the choice made.

The pick

On a pick, each star taken spins from −72 degrees (a fifth of a turn: the star looks the same again) and grows from 0.7, one every 0.06 seconds; the last one jolts up to POP. A slanted rectangle, cut to the stars taken only, passes over them like a glint, and the gradient’s two colours change with the number.

Fingers and the preview

A finger slides along the stars (touch-action: none) and the choice falls where it lifts; a plain tap goes through the radio. A click from a script on the stars (detail 0, the library’s preview) is a pretend hand: it runs along them all and picks three, four or five.

Values to change

NameFileDefaultWhat it changes
LABELSscript.js['Terrible', 'Not great', 'Okay', 'Good', 'Wonderful']The word for each number of stars (and how many stars there are).
STARTscript.js0The stars picked when the page opens (0 = none).
SPRINGscript.js[170, 0.78]The liquid’s spring: how stiff it is and how much it is held back.
WAVEscript.js3.2How much the liquid’s edge ripples while it moves, in pixels.
POPscript.js1.3How big the star picked gets.

Try them in the Playground

When to use it

For reviews of a place to stay or a restaurant, rating a product or a course, the questions of a survey: wherever you ask for a score from one to five.

On phones

The stars narrow with the screen. A finger slides along the stars to choose, without scrolling the page, and the choice falls where it lifts; a tap picks straight away.

With reduced motion

The gold reaches the star pointed at straight away, without running or rippling, the stars do not grow or spin, no glint: only the gold and the word change.

Pitfalls

  • Five home-made buttons would have to be rebuilt for the keyboard and for screen readers: with real radios under the stars, arrows, forms and reading work by themselves.
  • The liquid’s edge must stop between two stars, not inside one: that is why the level jumps the gap (a star’s width plus the gap) and at rest the edge falls right in the empty space.
  • On SVG the transform origin must be given to GSAP (transformOrigin), which works it out on each star’s box: a transform-origin in the CSS would add up with it and the stars would turn round another point.
  • The glint must pass over the gold only: it is cut by a clipPath made of the stars picked, rebuilt at every pick.

Libraries

GSAP 3.15.0, Fraunces (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 5.7 KB; the libraries: GSAP 28 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