This is THE most compact and optimized version of a pure CSS only HTML star rating. It covers a form input field as well as an output only score element.
I was searching a long time for a good CSS only solution for a star input field for my Grav Ratings plugin. I found a few ones (list a the end of this post), but they could still be optimized a lot or contained a few bugs. I’ve managed to sort them all out and give you the best version of a pure CSS star rating element.
Prerequisites
In order to get started I wanted to note, that the following code is based on Font Awesome 4, but also works with Font Awesome 5, Line Awesome 1.3 and even pure Unicode stars as well. You can also easily adapt other icon fonts as well.
Instead of writing pure CSS I have used the very common SCSS. It should be easy for you to convert it to CSS, if that is what you need instead.
Example
So here is a ready to use example which shows what we will be building in this posts. It contains a fixed star rating first, which can be used to show the user a rating summary and a form input field to let the user select the appropriate star rating.
The output fields work for half steps (0.5) as well, the input only accepts full stars. It can be easily tweaked to allow more than 5 stars, but I’ve chosen 5 here, as it is most common.
Step 1: Star Icon Definition
Before we start, we must declare how a star should look like. Since we are using Font Awesome 4 in this example, we need to lookup the font numbers of the corresponding star icons. Those definitions are used in the following steps again.
// Star definitions
%base-star {
display: inline-block;
&:after {
font-family: "FontAwesome";
font-size: 1.5em;
color: #FFC600;
}
};
%full-star {
@extend %base-star;
&:after {
content: "\f005";
}
};
%half-star {
@extend %base-star;
&:after {
content: "\f123";
}
};
%empty-star {
@extend %base-star;
&:after {
content: "\f006";
}
};
Code language: SCSS (scss)
And as promised a version for the Font Awesome 5 or Line Awesome users:
// Star definitions
%base-star {
display: inline-block;
&:after {
font-family: "Font Awesome 5 Pro", "Line Awesome Free";
font-size: 1.5em;
color: #FFC600;
}
};
%full-star {
@extend %base-star;
&:after {
font-weight: 900;
content: "\f005";
}
};
%half-star {
@extend %base-star;
&:after {
font-weight: 900;
content: "\f5c0";
}
};
%empty-star {
@extend %base-star;
&:after {
font-weight: 400;
content: "\f005";
}
};
Code language: SCSS (scss)
And even a pure HTML Unicode solution without any icon font at all!
// Star definitions
%base-star {
display: inline-block;
&:after, &:before {
font-size: 2em;
color: #FFC600;
}
};
%full-star {
@extend %base-star;
&:after {
content: "\2605";
}
};
%half-star {
@extend %base-star;
&:before {
position: absolute;
content: "\2606";
}
&:after {
position: absolute;
content: "\2605";
background: linear-gradient(to right, #FFC600 50%,transparent 50%);
background-clip: text;
// Experimental: https://caniuse.com/mdn-css_properties_-webkit-text-fill-color
-webkit-text-fill-color: transparent;
}
};
%empty-star {
@extend %base-star;
&:after {
content: "\2606";
}
};
Code language: SCSS (scss)
Step 2: Star Rating Score Element
The following simple CSS and HTML is used to output a CSS only star rating score element.
// 5 Star Rating Score
.rating-score {
display: inline-flex;
flex-direction: row;
align-items: flex-start;
margin: 0;
padding: 0;
.rating-score-item {
@extend %empty-star;
}
@for $i from 1 through 5 {
&[data-rating='#{$i}'] {
.rating-score-item:nth-child(-n + #{$i}) {
@extend %full-star;
}
}
}
@for $i from 0 through 4 {
&[data-rating='#{$i + 0.5}'] {
.rating-score-item:nth-child(-n + #{$i}) {
@extend %full-star;
}
.rating-score-item:nth-child(#{$i + 1}) {
@extend %half-star;
}
}
}
}
Code language: SCSS (scss)
Note the data-rating
attribute in the outer list element. It can be used to set the target rating score. You can also use half steps (e.g. 3.5) here.
<ul class="rating-score" data-rating="4.5">
<li class="rating-score-item"></li>
<li class="rating-score-item"></li>
<li class="rating-score-item"></li>
<li class="rating-score-item"></li>
<li class="rating-score-item"></li>
</ul>
Code language: HTML, XML (xml)
Step 3: Star Rating Form Input Field
Next we are creating the star rating form input field. It can be used in any form and will work like any other radio button. The CSS is quite tricky, as we need to make sure to overwrite the colors at a specific CSS selector level. Once I got there, it is pretty straight forward:
// 5 Star Rating Form Field
.rating-input {
border: none;
display: inline-flex;
flex-direction: row-reverse;
justify-content: flex-end;
margin: 0;
padding: 0;
> input {
display: none;
}
> label {
@extend %empty-star;
}
// Selected star color
> input:checked ~ label {
@extend %full-star;
}
// On hover color all stars grey by default
&:hover > input + label {
@extend %empty-star;
}
// Hover star color
&:hover > input + label:hover,
&:hover > input + label:hover ~ input + label {
@extend %full-star;
}
}
Code language: SCSS (scss)
And finally the minimum HTML, also quite simple:
<fieldset class="rating-input">
<input type="radio" value="5" id="stars-star5" name="rating">
<label for="stars-star5" title="5 Stars"></label>
<input type="radio" value="4" id="stars-star4" name="rating">
<label for="stars-star4" title="4 Stars"></label>
<input type="radio" value="3" id="stars-star3" name="rating">
<label for="stars-star3" title="3 Stars"></label>
<input type="radio" value="2" id="stars-star2" name="rating">
<label for="stars-star2" title="2 Stars"></label>
<input type="radio" value="1" id="stars-star1" name="rating">
<label for="stars-star1" title="1 Stars"></label>
</fieldset>
Code language: HTML, XML (xml)
Continue Reading
Now this looks quite simple, but it took me a lot of time to come to that final version. It is the most compact, best looking and clear CSS only star rating HTML element that I’ve found. In the links below you can find other codepens on which this solution is based on, but as an improved version.
- Borrowed from: CSS only star rating score element codepen
- Borrowed from:CSS only star rating form input field (with half steps) codepen
- 25 Awesome CSS Star Rating Examples
- CSS Tricks PostA and PostB about star ratings
- My Grav Ratings Plugin where you can see it in action
Did you find anything yet to improve more? Let me know in the comments!