CSS star rating

In this post I'd like to discuss with you a CSS solution for implementing a simple image gallery with a star rating system attached to it. To accomplish this task, we're going to use CSS image sprites for showing the various rates. A star rating system poses an accessibility problem. In fact, usually most developers use an empty element with no significant information to display the star icons. Instead, in this post I'm going to show you how to implement a more accessible solution that makes use of a CSS technique for replacing text. But first, let's start with our markup:

<ul id="gallery">
    <li><img src="star-rating/1.jpg" alt="" />
    <div class="rating five">Rate: 5</div></li>
    <!-- other five items -->

In this case, the alt attribute of each image is empty just because this is only a demo, but in a real world scenario you should always fill it with significant information. The element that will host our stars is called rating and has a relevant text within that tells what is the current rate for each image. Note also that this element will get a series of additional classes (five, four and so on) in descending order to properly display our CSS sprites. In that vein, our CSS sprite image is shown below.

First, let's build our image gallery:

#gallery {
    margin: 0 auto;
    padding: 2em 0;
    list-style: none;
    width: 90%;
    height: 100%;
    overflow: hidden;

#gallery li {
    float: left;
    height: 100%;
    display: block;
    margin-right: 0.5em;
    width: 15%;

#gallery li img {
    display: block;
    width: 100%;

Element's dimensions are expressed in percentages so that they will always fit the browser's window. Now our CSS sprites:

#gallery li div.rating {
    width: 104px;
    height: 16px;
    margin: 0.4em auto;
    text-indent: -1000em;
    background-image: url(star-rating/star-rating.png);
    background-repeat: no-repeat;

.five {
    background-position: 0 -77px;

.four {
    background-position: 0 -60px;

.three {
    background-position: 0 -43px;

.two {
    background-position: 0 -28px;
    position: relative;
    top: 2px;

.one {
    background-position: 0 -12px;

#gallery li div.zero {
    background-color: silver;
    background-image: none;
    position: relative;
    top: 3px;

First, all the textual content has been hidden in an accessible way using a negative value for the text-indent property. Then we've set the dimensions of our sprite container and specified our sprite image as its background image. Finally, all the heavy job is up to the background-position property and, more specifically, to the vertical position of the image. In this case, we use decreasing negative values to display the various rating levels. You can see the results in the demo below.


Live demo

This entry was posted in by Gabriele Romanato. Bookmark the permalink.

Leave a Reply

Note: Only a member of this blog may post a comment.