Introduction
A while ago, I was tasked with increasing the profile of the stars that we used to represent review ratings on our site. The main issue was that the stars were too small. Not a problem. A quick session in PhotoShop netted larger stars. But now a new problem arose. The smaller stars worked well on white or gray backgrounds. But the larger stars did not work on the gray backgrounds we used for alternate rows. One possible solution would be to have the engineers write some code that would switch out the stars on a white field with stars on a gray field when the striped row is used. But our engineers were busy with other projects that had higher priorities. How could I complete my little project without engineering assistance? The answer came in the form of the CSS Image Replacement technique applied to an image instead of text.
The Markup
Here is our file before the solution has been applied. On the actual site, the stars were laid out in a table structure, but for this demonstration, they are laid out in an unordered list structure.
<ul> <li> <div class="rateBox"> <img width="67.5" height="15" src="rateBar_bg.gif" /> <img src="rateStars.gif" class="rateStars" /> </div> </li> <li class="even"> <div class="rateBox"> <img width="65" height="15" src="rateBar_bg.gif" /> <img src="rateStars.gif" class="rateStars" /> </div> </li> <li> <div class="rateBox"> <img width="37" height="15" src="rateBar_bg.gif" /> <img src="rateStars.gif" class="rateStars" /> </div> </li> <li class="even"> <div class="rateBox"> <img width="35" height="15" src="rateBar_bg.gif" /> <img src="rateStars.gif" class="rateStars" /> </div> </li> <li> <div class="rateBox"> <img width="75" height="15" src="rateBar_bg.gif" /> <img src="rateStars.gif" class="rateStars" /> </div> </li> </ul>
A closer inspection of the markup reveals that the rating stars are actually a two-part graphic. The rating itself is represented by a bar that varies in width depending on the individual rating (dynamically set by the backend code). The stars are positioned over the rating bar. The body of the stars are transparent so what the user is seeing is the variable-width rating bar showing through the "cut-out" stars. Also note thatevery other LI or row has the class "even" to allow for the striping effect.
The CSS
The CSS is pretty basic. Some styling to format the list and the positioning of the star image over the rating bar.
body {
margin: 1em;
padding: 1em;
background: #fff;
}
ul {
list-style: none;
}
li {
padding: 1em;
}
li.even {
background: #e9e7d9;
}
.rateBox {
position: relative;
display: block;
height: 15px;
overflow: hidden;
}
.rateBox img {
position: absolute;
}
.rateStars {
width: 75px;
}
So far so good. But now we need to apply the image replacement technique to the stars when they are on a gray background. Since our template was already been engineered to insert the class "even" for the striped rows, we have what we need to create a selector that will allow us to attach a version of the stars with a gray background to the stars image, and then hide the original stars image so that the background image is revealed.
.even .rateStars {
padding-top: 15px;
background: transparent url(rateStars_alt.gif) no-repeat;
}
I set padding-top to 15px to push the original star image out of view. A negative text-indent value doesn't work here because IMG tags are considered empty, so there is nothing to indent one way or the other. Setting overflow: hidden on the parent DIV hides the part of the image that would be visible below the 15px top padding. The final result will reveal stars alternating between white and gray backgrounds.
Final Thoughts
This technique should perform solidly for FireFox, Opera, Safari and IE 7 and 6. No guarantees for earlier versions of IE. If you want to display the stars inline with other other text, along a blurb of text describing the rating for instance, the stars image height should be set to 0, and overlfow set to hidden to ensure that the white stars don't show through.
Follow any responses to this entry through the RSS 2.0 feed.
You can leave a comment, or trackback from your own site.





