Key insights
- Preview on hover, don't wait for the click. Stars should fill ahead of the cursor so users see the value they're about to commit — a widget that only reacts on click hides the target until it's too late.
- Keep the preview state separate from the committed value. When the pointer leaves without clicking, snap the display back to the saved rating; a naive build leaves it stuck on the last hovered star.
- For averages, render fractional stars — a 4.4 is four full stars plus a fifth clipped to 44%. Rounding it up to five full stars is a lie that inflates perceived quality.
- Stagger the fill ~30ms per star, left to right. Popping all five at once feels flat and lifeless; the sequential sweep feels alive.
- Use fractional fill for input precision too — clumsy whole-star jumps read as cheap next to a smooth half-star land.
- Stars are the input; pair them with a summary view (an average ring plus a distribution breakdown) to communicate the aggregate score at a glance.
Do / Don't
- Do: Fill stars ahead of the cursor on hover so the value previews before commit
- Do: Render partial fills so a 4.4 shows four stars plus a 44%-filled fifth
- Do: Stagger the fill roughly 30ms per star, left to right, when a rating commits
- Don't: Round averages up to full stars — it misrepresents the real score
- Don't: Leave the preview stuck on the hovered value after the pointer leaves
- Don't: Pop all five stars simultaneously — it reads as flat and dead