Star Ratings in CSS & UTF8
Ah, the ubiquitous star rating. A single simple concept with a hundred different implementations.
Let's make one using only UTF8 characters, CSS, and a single HTML element per star.
Here's what we'll be making: http://jsfiddle.net/M8UAy/
First, the markup:
<span class="star-icon">☆</span>
<span class="star-icon">☆</span>
<span class="star-icon">☆</span>
<span class="star-icon">☆</span>
<span class="star-icon">☆</span>
Keep it simple. This gives us five empty stars, but this protip is worth more than that!
Let's add some classes to fill in a solid 3.5 star rating. Satisfactory!
<span class="star-icon full">☆</span>
<span class="star-icon full">☆</span>
<span class="star-icon full">☆</span>
<span class="star-icon half">☆</span>
<span class="star-icon">☆</span>
Cool. Now we just need a little CSS. First, the grey, empty stars of dismay:
.star-icon {
color: #ddd;
font-size: 34px;
position: relative;
}
Then - the bright, shining stars of triumph!
.star-icon.full:before {
color: #FDE16D;
content: '\2605'; /* Full star in UTF8 */
position: absolute;
left: 0;
text-shadow: 0 0 2px rgba(0,0,0,0.7);
}
And finally, the mediocre half-stars of indecision:
.star-icon.half:before {
color: #FDE16D;
content: '\2605'; /* Full star in UTF8 */
position: absolute;
left: 0;
width: 50%;
overflow: hidden;
text-shadow: 0 0 2px rgba(0,0,0,0.7);
}
Check out that JSFiddle again if you want to see the result.
So, what's the trick here? We're using the empty star as a placeholder, then filling it in with the help of the CSS :before
selector paired with the content
property. This allows us to layer another full, yellow star on top.
The :before
selector creates a pseudo-element whose content is the UTF8 ★. This pseudo-element is then positioned absolutely so that it covers the original empty star.
For the half-star, the trick is nearly the same, but we set width: 50%;
and overflow: hidden;
so that only half of the full-star shows up, while the rest is cut off.
You may have noticed a dirty Firefox hack in that JSFiddle. Unfortunately Firefox renders the stars at a much smaller size, so to compensate I've set the font-size
higher for FF only. If you know what's causing this (or a better fix!) leave me a comment!
Also, it's possible to make the rating interactive on hover purely through CSS as well. Maybe something for my next protip ;)
★★★ 再见! ★★★
Written by Jim Greenleaf
Related protips
5 Responses
This works on Safari, Chrome and Firefox, but not on IE11
@veganoo - strange... it works in IE8+ for me. Did you work out what's going on in IE11?
Not sure what's happening - not a coder ;-) have a look at veganoo.net at the post dated today (21st Nov)
@veganoo - I'd look into the meta tag which is being set on that page: <meta content='IE=EmulateIE7' http-equiv='X-UA-Compatible'/>
. If that tag works in IE11 (which it appears to) then it would render without support for the :before
pseudo-element necessary to fill in the stars.
Thanks amoniker, that's probably it.