Pure CSS 5 Star Rating System with Radios

Why CSS?

Most well-known star based rating systems use JavaScript, or a combination of JavaScript & CSS. While these are a quick & easy solution for modern browsers, they rely entirely on JavaScript to work, which is never a great idea. We need a new solution!

Other Solutions

There is quite a well-known pure CSS star based rating system, which can be found here. It works by grouping-up a series of anchor tags, and changing their background position when a user hovers over a star. Which is great! But not very useful, as you would still need to use JavaScript to add the result to an HTML form for submission, or submit the rating each time a user clicks on one of the anchor tags. You could work-around this with some basic JavaScript, but we're back to our root problem again.

My Solution

So today I'm sharing my creation, a PURE CSS star based rating system, using actual HTML radio buttons. This is by no-means fully tested, so I'd love to hear your feedback. I've confirmed it working in FireFox, Google Chrome, IE 9, and several mobile browsers. Go ahead, try it...

The Catch

In-order for the general-sibling combinator selector ( ~ ) to work correctly, at-least one radio must be checked. This is easily solved however, with a hidden radio option.


<div class="rating">
<input type="radio" name="rating" value="0" checked /><span id="hide"></span>
<input type="radio" name="rating" value="1" /><span></span>
<input type="radio" name="rating" value="2" /><span></span>
<input type="radio" name="rating" value="3" /><span></span>
<input type="radio" name="rating" value="4" /><span></span>
<input type="radio" name="rating" value="5" /><span></span>

What we're here for: The CSS

#hide {

.rating input {

.rating span {
padding:1px 22px 1px 0; /* 1px FireFox fix */
background:url(stars.png) no-repeat -22px 0;

/* Change span immediately following the checked radio */

.rating input:checked + span {
background-position:-22px 0;

/* Reset all remaining stars back to default background.
This supersedes the above due to its ordering. */

.rating input:checked + span ~ span {
background-position:0 0;


The only pseudo selector used in the above example is the :checked selector, so compatibility-wise it is the weakest link. IE 9 & above, and all other major browsers should be fine. For IE 6 to IE 8, we can use a JavaScript fallback to make it work, such as Selectivizr. For more information on dealing with IE, see this article.

Article Updated: Tue 18th Dec 2018