I had this idea, that I could use the CSS gradient background to display the ratings of a restaurant. The results might be more interesting, than useful, but it certainly has some pros as well. At the end, it may look something like this:

Hearts and stars filled with gradient

In this example the rating can be set from 0 to 5 with 1/100 increments (or smaller I guess, if that makes sense). Looks the best though if I don’t go beyond 0.5 increments as otherwise it’s not really a pixel perfect solution.


Not much to explain here. This structure allows me to label the content for screen readers while hiding the Unicode characters. Those are useless and/or confusing unless you can actually see them


I’m yet to fully understand how exactly the CSS gradient background works when you add multiple stops. Not gonna lie, I’ve played around a bit with the values to reach a satisfying state. Originally I tried with color values #f22, #f22 ${fill}%, #000 20%, #000 80%, but if I used a rating less than 1 (<20% fill) it started to show gradient in the first character. That 20% was suspicious and changing it to what you see here, with the black values set to #000 1%, #000 99%, it works as I want it. The background is clipped to the text and the text I made opaque with rgba. The text shadow adds a little 3D feeling to the whole.


As this example uses a 0-5 rating, the data-rating value is multiplied by 20 to reach a 0-100% fill. Obviously, for a 0-10 option change the multiplier to 10. I also add an aria-label with the details for screen readers. I was thinking about reusing one of the ARIA range role (the range itself is an abstract role), but none seem to really match and I was afraid it may cause confusing. Otherwise a subclass of range, with the min/current/max value might be a good choice. The last line of code was necessary, because to be honest, this solution is quite fragile. If a whitespace is added somewhere, for example because of the structuring of the HTML elements, it will mess the gradient up. To fix that, either got to make sure there is no whitespace or like I did, remove it from JS.

Further ideas

  • change the gradient color based on the rating
  • add styling option, e.g. add a data-color to the HTML elements and use it from the JS
  • add transition effect, for example on the background-size

If you want to play around with the code, I’ve added it to CodePen:

See the Pen Gradient rate by Gabor S. (@seabadger) on CodePen.

Add control

I’ve also created a small code snippet to get you started if you want to create a control (slider). You can check out the code here:

See the Pen Gradient rate control by Gabor S. (@seabadger) on CodePen.

Tagged with