22 CSS Star Ratings
22 production-grade CSS star rating designs you can copy-paste into any project — pure CSS radio-button stars with reverse-flex sibling fill, modern :has() sibling combinator pattern, half-star fractional precision, animated bursting SVG particles, accessible ARIA fieldset rating, read-only review display, emoji feedback reaction scale (😞😐🙂😊😍), neumorphic soft-UI stars, CSS variable live customizer, vertical sidebar e-commerce filter (Amazon-style "4★ & up"), gradient-filled luxury stars, single-star numeric ticker, heart-based favorite scale, tooltip hover labels, plus 8 experimental concepts: liquid mercury morphing, holographic scanner, neural pulse feedback, magnetic field lines, quantum superposition, DNA helix strand, particle constellation, and glitch corrupt-and-resolve. Every star scoped under a unique .sr-NN prefix so all 22 coexist on this page without style bleed; every @keyframes name namespaced sr-NN-*; every @media (prefers-reduced-motion: reduce) guard already wired in. Real <fieldset> + <legend> + <input type="radio"> markup on interactive demos so screen readers announce ratings correctly.
Related25 CSS Testimonials & Reviews24 CSS Radio Buttons18 CSS Product Cards
Course pickPartner: Zero to Mastery
Affiliate linkWant to build production-ready CSS layouts, animations and UI from scratch?
You just browsed 22 star ratings. Learn the Flexbox, Grid and animation thinking behind them, so the next component starts in your head, not in a copy-paste.
Every ZTM course in one membership: $25/month, paid yearly at $299 · 30‑day money-back guarantee
The CSS Bootcamp. We may earn a commission, at no extra cost to you.
02. Modern CSS Star Rating using has() (opens in a new tab)
03. CSS Half Star Rating (opens in a new tab)
04. Animated Bursting SVG Star Rating (opens in a new tab)
05. Accessible ARIA Star Rating (opens in a new tab)
06. CSS Star Rating for Read-Only Reviews (opens in a new tab)
07. Emoji Feedback Reaction Scale (opens in a new tab)
08. Neumorphic Soft Star Rating (opens in a new tab)
09. CSS Variable Star Customizer (opens in a new tab)
10. Vertical Sidebar Rating Filter (opens in a new tab)
11. Gradient Filled Star Rating (opens in a new tab)
12. Single Star Numerical Rating (opens in a new tab)
13. Heart-Based Favorite Rating (opens in a new tab)
14. CSS Tooltip Hover Star Rating (opens in a new tab)
15. Liquid Mercury Morphing Rating (opens in a new tab)
16. Holographic Scanner Rating (opens in a new tab)
17. Neural Pulse Feedback Rating (opens in a new tab)
18. Magnetic Field Lines Rating (opens in a new tab)
19. Quantum Superposition Rating (opens in a new tab)
20. DNA Helix Strand Rating (opens in a new tab)
21. Particle Constellation Rating (opens in a new tab)
22. Glitch Corrupt-and-Resolve Rating (opens in a new tab)
Frequently asked questions
How do I create a pure CSS star rating without JavaScript?
<input type="radio" name="rating"> elements in a container with flex-direction: row-reverse, so earlier inputs (higher star values) sit to the right in the DOM but render left-to-right visually. Use the ~ general sibling combinator (input:checked ~ label::before) to fill every label *after* the hovered or checked one — which in reversed order means all stars of lower value — creating the cascade fill purely in CSS. (2) The modern :has() pattern (Demo 02): keep the inputs in natural DOM order and use .stars:has(#s4:checked) label[for^="s1"] ::before { color: gold } to drive fills from the parent. :has() is supported in all modern browsers as of 2023; if you need to support older Safari/Firefox, fall back to the reverse-flex trick. Both patterns are 100% CSS — no JS, no libraries — and stay keyboard-accessible because the native radio inputs handle focus, arrow keys, and form submission. Every demo in this collection ships the full HTML + CSS so you can paste it into your project.How do I make a half-star rating display in CSS?
<span class="star"> with two child elements (or two pseudo-elements). The gold layer uses clip-path: inset(0 50% 0 0) (right-side cut) for an exact half, or width: 50%; overflow: hidden for variable precision. For a read-only display showing 4.5 stars: the first four are fully gold, the fifth gets 50% gold-layer width. For variable values (e.g. 4.3), compute (value % 1) * 100% and inline the result on the partial star — CSS-only, no JS needed if you generate the markup server-side. Every Amazon, Yelp, and Trustpilot review widget you've ever seen uses some variant of this exact pattern.How do I make my star rating accessible to screen readers?
<fieldset> with a <legend> describing what's being rated ("Rate this product"), so screen readers announce the context. (2) Each star is a real <input type="radio"> paired with a real <label> — never style a <div> to look like a star unless you fully implement the ARIA radiogroup pattern with keyboard handlers. (3) Visually hide the radio buttons with clip-path: inset(50%) or position: absolute; opacity: 0 (NOT display: none, which removes them from the accessibility tree). (4) Give each label visible-only text like <span class="sr-only">1 star</span> so a screen reader announces "1 star, radio button" instead of just "radio button". (5) Add a clear :focus-visible outline on the labels so keyboard users see where focus is. Demo 05 (Accessible ARIA Star Rating) ships all five rules with a real <fieldset> + <legend>, screen-reader-only labels, focus rings, and arrow-key navigation (free from the native radio group). Cite WCAG 2.1 SC 1.3.1 (Info & Relationships) and 4.1.2 (Name, Role, Value) in your audit notes.What's the difference between an interactive and a read-only star rating?
<input type="radio">) so the value posts with the form, focus and arrow keys work, and the value is available to JavaScript via form.elements.rating.value. Read-only ratings just *display* an existing aggregate value ("4.5 stars from 312 reviews") — they don't need inputs at all; use semantic markup like <output> with aria-label="Rated 4.5 out of 5 stars" so screen readers announce the value, then style with the same star clip-path approach as Demo 06. Common mistake: shipping interactive markup for a read-only display — it adds DOM weight, makes screen readers prompt "radio button: select to change" (confusing for a display value), and the focus ring traps keyboard users in non-functional widgets. Demo 06 is the read-only reference; Demos 01, 02, 03, 05 are the interactive references.How do I add half-star precision to my read-only ratings?
(value % 1) * 100% width. The arithmetic: if value is 4.5, render the first 4 stars fully gold, the 5th with width: 50%. If value is 4.3, the 5th star is 30%. Three approaches: (a) **inline style** — server renders <span style="width: 30%"> on the partial star. Simplest, no JS. (b) **CSS custom property** — <div style="--rating: 4.3"> and CSS calculates width: calc(var(--rating) * 20%). Cleaner data binding. (c) **CSS conic-gradient** — single SVG star path filled with a conic gradient where gold ends at (value / 5) * 360deg. Most elegant but trickier to get right at small sizes. Demo 03 (interactive) and Demo 06 (read-only) cover all three approaches. For dynamic values from an API, approach (b) is usually best — JS just updates the CSS variable, the CSS handles the visual update.Can I use CSS-only star ratings without losing Lighthouse accessibility scores?
<label for> paired with <input>); (2) sufficient color contrast (yes if your gold passes 3:1 against the unfilled gray; check with the WebAIM Contrast Checker — #FFB000 on #fff is 1.97:1 against text but passes the 3:1 "non-text contrast" requirement for UI components in WCAG 2.1); (3) keyboard accessibility (yes — native radio groups handle arrow keys); (4) screen-reader announcements (yes if you wrap in <fieldset> + <legend>); (5) focus visibility (yes if you add :focus-visible outlines). Demo 05 (Accessible ARIA) ships all five — drop it into your page and Lighthouse will score it 95-100 on accessibility. Common Lighthouse failure: hiding inputs with display: none instead of clip-path removes them from the a11y tree and breaks every screen reader. Use clip-path: inset(50%); position: absolute instead — visually identical, accessibility-tree-intact.How do I customize the star color or size at runtime?
.sr-09 { --star-fill: #FFB000; --star-empty: #e5e7eb; --star-size: 36px; --star-gap: 8px }. Then reference them in every internal rule: .sr-09__star { width: var(--star-size); height: var(--star-size); fill: var(--star-empty) } and .sr-09__star.is-filled { fill: var(--star-fill) }. Now JavaScript (or even another CSS rule based on data-theme="dark") can update the variables and every star recolors at once: el.style.setProperty('--star-fill', '#ec4899'). The same approach scales sizes (40px → 60px for a hero CTA), spacing, animation duration, and even the star shape (swap clip-path polygons for different star styles). For React, pass variables as inline style: <div style={{ '--star-fill': brandColor }}>. For Tailwind, use [--star-fill:#FFB000] arbitrary-value syntax. No re-compile, no rebuild — just update the variable.How is this different from FreeFrontend, FrontendPlanet, W3Schools, dev.to, or rating libraries like React Stars / Vue Star Rating?
.sr-NN namespace (no collision when pasting two demos into one project), every @keyframes is prefixed sr-NN-*, every element ID is sr-NN-*. The big gallery sites (FreeFrontend, FrontendPlanet, uiCookies) curate links to CodePen demos with generic class names like .rating, .stars, .star that collide when pasted together. **(2) Modern patterns**: this collection ships both the *classic* radio-button + reverse-flex pattern (works everywhere) AND the *modern* :has() pattern (Chrome 105+, Safari 15.4+, Firefox 121+ — 95%+ browser support today). W3Schools and most tutorial sites still teach only the reverse-flex hack and never mention :has(). **(3) Accessibility by default**: every interactive demo ships a real <fieldset> + <legend>, real <input type="radio"> + <label>, clip-path: inset(50%) hiding (not display: none), :focus-visible outlines, and prefers-reduced-motion guards. React-Stars / Vue-Star-Rating libraries are ~5-15KB gzipped, render their own DOM (often missing real form inputs), and need wrapper code for accessibility. This collection: 0 KB of dependencies, real form inputs, MIT-licensed, no signup. Free, copy-paste, ship today.Related collections
15 CSS 3D Tilt Hover Cards
15 mouse-aware 3D tilt hover cards — e-commerce product spotlight, glassmorphism parallax team card, interactive pricing tier, holographic NFT collectible, pop-out mascot, dark tech grid with border glow, media player album art, blog article preview, cyberpunk neon glow, dashboard KPI widget, minimalist real estate, flip-to-back tilt, mobile app showcase, course learning card, and a Pure CSS touch-friendly tilt. Vanilla JS writes --rx/--ry/--mx/--my; all rendering stays in CSS on the GPU.
24 CSS Animated Cards
24 hand-coded CSS animated card patterns organised by what triggers the motion, not by card style. Scroll and entrance triggers: staggered grid reveals, @starting-style mount-in, scroll-driven scale and fade on animation-timeline: view(), View Transitions API card-to-detail morphs, blur-to-sharp lazy image loading, and FLIP re-layout when a filter changes. State-change triggers: add-to-cart success morph, like and save particle burst, expand and collapse to intrinsic height with calc-size(), swipe-to-dismiss on Pointer Events, and skeleton-to-loaded crossfade. Data-driven triggers: count-up KPI metrics, SVG sparkline draw-on-enter, and progress ring fill on load. Ambient idle loops: breathing glow, floating drift, animated gradient mesh backgrounds, conic rotating borders, auto-cycling testimonial decks, and live status pulses. Plus four hover patterns where the effect is the topic itself: cursor spotlight, holographic foil glare, corner ribbon slide, and horizontal accordion expand. Every card is scoped under a .ac-NN prefix for no-collision pasting, guards prefers-reduced-motion, animates compositor-only properties, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
22 CSS Avatars
22 hand-coded CSS avatars for chat apps, team dashboards, comment threads, account menus, and social profiles. Covers circular and squircle shapes, gradient and conic story rings, hexagon clip-path crops, online status dots, notification count badges, verified checkmarks, stacked facepiles with plus-N overflow, initials fallbacks for users without photos, broken-image recovery, avatar pickers, and a size scale system where the ring, badge, and status dot all scale from a single custom property.





















