Today I thought about a project I had in mind for some time, it has to do with ratings of different contents and the first thing I thought about was: What’s the easiest or best way to create a rating form with custom buttons (stars, hearts, whatever).
A few years ago I had to do this once and I remember doing it with an image and background-position
but as of today I really love pseudo elements and “Look-Ma-No-Image!”. However I decided to use Icon Fonts this time and play around a bit with them. My HTML Markup is very simple:
<input type="radio" data-rate="1" name="rating" class="rating--star" />
<input type="radio" data-rate="2" name="rating" class="rating--star" />
<input type="radio" data-rate="3" name="rating" class="rating--star" />
<input type="radio" data-rate="4" name="rating" class="rating--star" />
<input type="radio" data-rate="5" name="rating" class="rating--star" />
That’s it: A group of radio inputs
representing a rating system with 1-5 possible choices. The CSS part is a little bit trickier (note that I’m using Sass with SCSS Syntax!)
.rating--star {
color:#ff7711;
&:before {
content:"\2605";
font-size:2em;
font-family:entypo, sans-serif;
}
&:checked ~ :before {
content:"\2606";
}
&:focus {
outline:0;
}
}
A small piece of code, yet it can seem complicated. I’ll break it down a bit.
.rating--star {
color:#ff7711;
@include appearance(none);
&:before {
content:"\2605";
font-size:2em;
font-family:entypo, sans-serif;
}
The first part represents the class itself and the :before
pseudo element that holds the icon (in this case a Star from the entypo icon font served via We Love Icon Fonts), I set the color on the element directly because the :before
and :checked ~ :before
are using the same color. appearance:none;
removes the User Agent style from the input element or, in other words, “hides” the element.
&:checked ~ :before {
content:"\2606";
}
The next line says “when the input is :checked
change the properties of :before
”. So when it is checked I want the filled Star to show up ("\2606"). Seems logical? It’s not. \2606
is the empty star. So the &:checked ~ :before
pseudo holds the icon that should be included if the button is not checked and the :before
holds the checked (in this case filled) icon. This is because :checked ~ :before
selects every element that is preceded of the :checked
element. This comes handy because this also means all inputs display a filled star if we check the last star (and that’s exactly what we want).
A live demo can be found on CodePen.