DEV Community

Discussion on: CSS SVG star rating ⭐️

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

It'd be so nice if we could just do

.star:nth-child(attr(rating)) { ... }
Enter fullscreen mode Exit fullscreen mode

and just use an attribute to do these things.

Setting that aside, here's a few things I don't completely like about this code:

  1. Instead of using nth-child and transform, you could just add x and y attributes to the use element.
  2. Although symbols don't get drawn regardless, it's still a good idea to put them in a <defs> block at the beginning of the document for readability.
  3. You really only need one star; you can just set the fill from CSS and if necessary use a gradient with a hard edge for half stars.

This is what I came up with after some tinkering:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg rating="2" xmlns="http://www.w3.org/2000/svg" version="2" viewBox="0 0 250 50">
    <defs>
        <style>
            .star { fill: gray; }

            [rating="1"] .star:not(:nth-child(n+2)) { fill: gold; }
            [rating="2"] .star:not(:nth-child(n+3)) { fill: gold; }
            [rating="3"] .star:not(:nth-child(n+4)) { fill: gold; }
            [rating="4"] .star:not(:nth-child(n+5)) { fill: gold; }
            [rating="5"] .star:not(:nth-child(n+6)) { fill: gold; }
        </style>
        <path id="star" d="M 25,0 31,18 50,18 34.5,29.3 40.4,47.5 25,36.3 9.5,47.5 15.5,29.4 0,18 19.1,18.2 Z" />
    </defs>
    <g>
        <use class="star" x="0" href="#star" />
        <use class="star" x="50" href="#star" />
        <use class="star" x="100" href="#star" />
        <use class="star" x="150" href="#star" />
        <use class="star" x="200" href="#star" />
    </g>
</svg>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dailydevtips1 profile image
Chris Bongers

Yeah, attribute nth-child would be a nice one, hey.

Your right could actually have swapped for x on the use. You know how you get into this code and debugging, and then it sticks, haha.

As for your one star, that's not completely true. Since you want dynamic colors based on the same, it's almost impossible to overwrite the color then or do the half stars.

I'll put this on my list to refactor to use the x instead of the nth-child.
Also, you could have defs and created fixed defs for each option so you can just use 1 single-use, but that's if you need all of them.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Half-stars can easily be done using a linear gradient with two stops at 50% (you can even move it around at random). As for the dynamic colours, I don't really get what you mean by that. Unless you want to change the actual shape of the star, almost everything can be done using CSS.