Semantic Star Rating HTML Widget

I am going to deviate this week from the Json Object discussion, as I have not had any time to work on it. Instead, I wanted to share a technique you can use to write semantic HTML for a rating system. If you have ever used a site like Amazon.com or Yelp.com, then you are familiar with the star rating system (0 stars = worst rating, 5 stars = best rating). However, most rating systems do not do a good job when browser font-size or zoom changes, making them inaccessible. Also, most tend to use a different graphic for each rating, requiring up to 10 graphics to load. The technique I worked on this week, not only scales well, but only requires 2 graphics, and you can change the color of your ratings with simple CSS.

Step 1: Create 2 Images

First decide which size you want the image to normally be (for me this was 80px wide by 16px high); this is a 1 to 5 ratio, because I am going to use a 5 point rating system, which will play an important role for the size of each rating point symbol. Use a program like Photoshop to create an image with these dimensions and a transparent background. In a separate window create an 16 x 16 (or 1/5 of the default width you chose) transparent image and draw in the symbol you want to use for the rating point (I used black for the color of my symbol, but it is up to you). I used a star, but it doesnt matter what you choose so long as the center is transparent and the symbol fills the dimensions. All spaces outside the symbol should be the background color of your page (this is white for my example page). Here is an example of my star:

Example 1: Star Graphics

Single star graphic

Single star graphic

The first graphic shows what "star.gif" looks like by default. The second show, the difference when a background color is applied. I choose red, but you can change it to whatever hex you prefer.

Next copy your 16x16 symbol image 5 times into the original image you created. You should have something that looks like the following:

Example 2: Rating Graphics

5 star graphic

5 star graphic

Example 2 is the first image we will need. I made the background yellow to show how easy it is to change. The second image we need is a background masking image used to cover the part of the rating inverse (if the rating is 1.5, then this will cover the other 3.5 of the symbols). The background should be the color of the site background (white for me), and the left-most pixels should all be the color of the symbols (black for me). This image should be taller and wider than the rating image, because it will need to scale as the browser does. I usually do 2x the original dimensions, which supports up to a +4 font-size. Therefore, the dimensions of my "ratingbg.gif" is 160x32px:

Example 3: Rating Background Graphics

5 star graphic

The gray border is only here to show contrast so you can see what the image looks like. The small sliver of black on the left will be the line that marks the rating position inside of the symbols. This completes all the images and HTML you will need to get the rating system to work.

Step 2: Create Styles to Control the Ratings

Next we style the image tag to support our ratings. I suggest using classes, here are the styles I used:

Example 4: Rating Styles

img.rating {
	background: #FC0 url(/assets/img/bg/ratingbg.gif) 5em 0 no-repeat; /* specify your color; 5 em is the 5:1 ratio; and the url is wherever the ratingbg.gif is located */
	font-size: 1.6em; /* this is the height of a single symbol; mine is 16px */
	height: 1em; /* this will cause the image to scale as the font-size changes, default is 16px */
	width: 5em; /* this the 5 to 1 ratio that I mentioned, but could be different if your symbols arent symetric */
}

/* higher specificity than img.rating */
html body img.r9 {
	background-position: 4.5em 0;
}

html body img.r8 {
	background-position: 4.0em 0;
}

html body img.r7 {
	background-position: 3.5em 0;
}

html body img.r6 {
	background-position: 3.0em 0;
}

html body img.r5 {
	background-position: 2.5em 0;
}

html body img.r4 {
	background-position: 2.0em 0;
}

html body img.r3 {
	background-position: 1.5em 0;
}

html body img.r2 {
	background-position: 1.0em 0;
}

html body img.r1 {
	background-position: 0.5em 0;
}

html body img.r0 {
	background-position: 0 0;
}

Step 3: Tie it all Together

Here is a rating of 2.5 in yellow, 1 in blue, and 4.5 in green:

Example 5: 3 Star Rating Variations

2.5 in yellow rating example
1 in blue rating example
4.5 in green rating example

The image heights in this article are slightly off by a fraction, due to rounding issues with other styles inherited in this wordpress theme. I have also created a test page so you can play with the uncorrupted styles and view them in different browsers. Try to scale the font-size and see how nicely the images scale and the rating stays in the appropriate place.