Configurable Star Rating Without JS Redux

The other day, I saw an interesting Sass example of a configurable star rating without JavaScript by Roy Tomeij. I was drawn to several aspects of the approach but noticed that you couldn’t click to “select” a star rating – so I decided to fork his example and update it with that behavior.

Click “Result” to try it out.

Play with this gist on SassMeister.

Some interesting things to note from Roy’s implementation are that the stars are each repeated backgrounds that are stacked on top of each other, with shorter star ratings having a higher z-index so that they are correctly clickable. Think of them like stairs:

  • 1-star is the highest stair
  • 2 stars is the next one down
  • the furthest star to the right (variable star count) is the lowest stair

Using this approach, when you click on the star furthest to the left, the 1-star stair is highest so you can only click on that one.

I changed the individual stars from being represented in markup by a tags to being label tags and controlling state via associated radio buttons. Whenever you click on a Star, you are clicking on the label which triggers the associated input[type="radio"] to be checked. Then, in the CSS, we can use something like the following to manage the displayed star state (I had to introduce a new star color for the “checked” state):

Whenever the radio button for a particular star is checked, we use the input[type="radio"]:checked + label selector to style the selected stars but the label:hover selector to style the stars that would be selected if you clicked.

It is a little awkward in that if you select a rating of say 3 stars, then hover over 5 stars, only stars 4 and 5 highlight. This is due to the stair-step z-index described above. There isn’t a good way to fix this without JavaScript but it is somewhat OK because it indicates which stars will be highlighted in addition to the already-highlighted stars.