Advertisement

Modern CSS Star Rating Component

| by Vladimir | 2 min read | code by Tommy Ho
A11y Ready Intermediate

Tech & Dependencies

HTML SCSS

Features

  • CSS :has() Logic
  • Clip-path Shapes
  • JS-free Interaction
  • Keyboard Accessible

Browser Support

Chrome 105+ Edge 105+ Firefox 121+ Safari 15.4+

Core

This Modern CSS Star Rating Component represents a major shift in UI development, moving complex logic from JavaScript to pure CSS. It utilizes the powerful :has() selector to track sibling states, allowing the UI to highlight stars both before and after the interaction point. The stars themselves are created using clip-path instead of bulky SVG icons, resulting in a lightweight, scalable, and highly performant rating system.

Core Technique

The “secret sauce” of this component is how it handles backward selection. Traditionally, CSS could only select “forward” (using the ~ combinator). By using .star:has(~ .star:hover), we can now style a star if any of its succeeding siblings are being hovered. This allows the component to fill the entire range from the first star to the current cursor position or the selected value.

Visually, the stars are constructed using two pseudo-elements (::before for the border/outline and ::after for the fill). Both use a complex polygon() clip-path to define the five-pointed shape. When a radio button is checked, the component uses :has(:checked) to scale up the selected star and update the --star-bg variable across the relevant range, providing a fluid, reactive feel.

Customization

The component is built with maintainability in mind, using CSS variables for key visual properties. You can easily adjust the theme, sizing, and animation speeds.

.star-rating {
  /* Change the primary highlight color */
  --star-rating-bg: gold;
  /* Adjust font size to scale the entire component */
  font-size: 1.75rem; 
}

.star::after {
  /* Fine-tune the transition speed */
  transition: all ease-in-out 333ms;
}

/* Modify star shape */
.star::before, .star::after {
  /* Change polygon points for different shapes */
  clip-path: polygon(50% 0%, ...);
}

Tips

1. Accessibility (A11y): Unlike many “hacked” CSS rating systems, this one uses native <input type="radio">. This means it works perfectly with keyboard navigation (Tab and Arrow keys) out of the box. To ensure users can see where they are, we use :focus-visible:

input[type="radio"]:focus-visible + label {
  outline: 2px solid gold; /* Clear keyboard focus indicator */
}
Advertisement