An updated and more cross-browser compatible version of the CSS star rater can be found here.

My last CSS tutorial, Creating a Star Rater Using CSS covered the creation of a 5-star rating system using only CSS and a list of links. The result acheived can be seen below:

Rate me!
Here is the original CSS star rater in all of its goodness. However, I have mixed it up a little to show that this system is decently flexible. In this case, I have changed the background images for the star graphics and made them a little larger.

Now, this rater works great in practice, but it is missing one essential thing: state. This star rating system does not have a initial state exept for a zero star rating. This is not good enough. We need to be able to start off with a specific rating, say 4 stars or 3 stars. Better yet would be a rating of 3.5 stars. As you know, when you average a rating from many users, you will most likely not get an exact integer number. Most likely you will come up with a rating such as 3.76 stars. How do you do this with CSS? That is the question I aim to answer.

If you don’t understand how the CSS works for the basic star rater that you see above, be sure to do your homework and head on over to the original article for the CSS star rating before you continue.

Now, I hate over complicating things, so I am going to keep this as straight forward as possible. First I will introduce you to my solution to this issue, I will then explain my approach, then I will present you with the CSS and a brief explanation of how it works.

Step 1: Check it in action

Everybody wants to see the result before they do the work, so lets do that. Here she is, in her full shiny glory:

Here’s a few more:

2.5 stars

0 stars

4 stars

Step 2: The XHTML

<ul class='star-rating'>
<li class='current-rating'>Currently 3.5/5 Stars.</li>
<li><a href='#' title='1 star out of 5' class='one-star'>1</a></li>
<li><a href='#' title='2 stars out of 5' class='two-stars'>2</a></li>
<li><a href='#' title='3 stars out of 5' class='three-stars'>3</a></li>
<li><a href='#' title='4 stars out of 5' class='four-stars'>4</a></li>
<li><a href='#' title='5 stars out of 5' class='five-stars'>5</a></li>
</ul>

Basically, the star rater is setup exactly the same way as previously shown. The only difference you will see is in bold. All that we have done here is add one more list element. This element has a class of “current-rating” and has some descriptive text for those browsers that aren’t too cool with CSS. Also, this text is great for screen readers. Don’t worry about this text showing up because we are going to push it off the screen and show the graphical equivalent of 3.5 stars in its place. Pretty simple huh?

Step 3: The Star Image

Don’t ask me why, but we are going to create the star image just a little differently. We are going to make a 3-state image. State 1 will be for the empty, non-rated star. State 2 will be for the current rating. State 3 will be for the user’s rating. Basically the user will hover the star rater and see a different state for when they are choosing their rating. Nifty.

Why a different state image and not just reset the image when a user hovers, using the already showing state? Good question and I am very glad that you asked it. When I first created this thing, I had that same idea. Without boring you with the headache that I had, let me say that it involved me making the list element that housed the current rating a link, then when that link was hovered, I made the width of the link set to 0. Well, as you may have thought, the resulting outcome in IE and Firefox was really really jacked up. It would flicker like heck and do a crazy song and dance and was really unfriendly. Then, I thought to myself, self what should we do? The troubles came from the current state being a link and the links being unfriendly on top of eachother, so I decided to make it a list element with the hover event on the list element like so: li:hover. If any of you know what comes next is pretty dang frustrating to all CSS developers. You got it. Some evil nerd with a lot of money made a proprietary browser that does NOT support :hover pseudo events on list elements. Basically, to make this solution work in IE, you have to get all crazy up in your code and include a csshover.htc file to make the browser realize how to make hover events work. Only problem. You HAVE to have JavaScript turned on. Screw that.

It came to me in a dream. Have a 3-state star rater. This will fix the problem. Hence we find ourselves with this 3-state star image that is o-so-beautiful:

Star Rater Dimensions

Step 4: The CSS, the Magic

  1. .star-rating li.current-rating{
  2. background: url(star_rating.gif) left bottom;
  3. position: absolute;
  4. height: 30px;
  5. display: block;
  6. text-indent: -9000px;
  7. z-index: 1;
  8. }

This time around, we are building on the previous CSS from the tutorial creating a star rater using CSS so the CSS should be pretty small.

The first CSS code that you will notice is the background tag. This list element will have…you guessed it, the same background as all of the other elements. In this case the background has three states: unrated, rated, and currently rating. Keep in mind that some CSS has changed from the original article to make the new background image work for this three state rater. Back to the rater. This list element will contain the current rating for whatever object/article you are using it for.

The next line of CSS is the position:absolute. Because the containing UL of this rater is positioned relatively, that means that this list will be relatively absolute. So if this list element is put at coordinates left:0px, top:0px, it will be located at those coordinates relative to the parent unordered list, NOT to the main window.

The next CSS rules are pretty simple. height:30px does what you think it does – it forces the height of the li element to be as high as all of the other stars. The display:block rule is in place because in the previous tutorial the style .star-rating li declares the list element to be a left floating list element. Now, we will be able to adjust the width of the current-rating list element to how many stars is the average rating. The text-indent rule just moves the text off of the screen so that the user doesn’t see it anymore (an image replacement method). Last, but definitely not least is the z-index: 1 rule. This will cause the current rating to be at a z level of 1, basically the bottom of the stack. We have set the z-index of the a:hover state for the rating links to be at z-index:2. This causes the links to hover over the current rating image and that is exactly what we want. We want our rating to be visible over the current rating so that we can see what we are rating. Yeah, that makes sense.

Thats pretty much all of the CSS for the new current rating addition. We just have a few things left to cover. I mentioned that the image is a three state image so we had to change some of the CSS in the previous tutorial. Basically, and CSS rules declared that use the background now have to be changed. First, we have to change the CSS delclaration for the main star-rating unordered list:

  1. .star-rating{
  2. background: url(star_rating.gif) top left repeat-x;
  3. }

Here, we just merely changed the background position on the y-axis to be at the top. That way, initially you will see the unrated star. Perfect. On to the next declaration. The next declaration we have to change is the CSS declaration for the hover state for the rating links:

  1. .star-rating li a:hover{
  2. background: url(star_rating.gif) left center;
  3. }

Once again this will be an easy change. Here, we will change the active rating state to the center image. So when the user hovers the rater, they will see the vertically centered image as hover image. Neato.

The very last thing I want to mention is how to change the current rating. I showed it in the examples above, but here is the final word. Check out this code snippet to see how I did it:

  1. <ul class=’star-rating’>
  2. <li class=’current-rating’ style=’width:105px;’>
    Currently 3.5/5 Stars.
    </li>
  3. <li>
    <a href=’#’ title=’1 star out of 5′ class=’one-star’>
    1 star
    </a>
    </li>
  4. <li>
    <a href=’#’ title=’2 stars out of 5′ class=’two-stars’>
    2 stars
    </a>
    </li>
  5. <li>
    <a href=’#’ title=’3 stars out of 5′ class=’three-stars’>
    3 stars
    </a>
    </li>
  6. <li>
    <a href=’#’ title=’4 stars out of 5′ class=’four-stars’>
    4 stars
    </a>
    </li>
  7. <li>

    <a href=’#’ title=’5 stars out of 5′ class=’five-stars’>
    5 stars
    </a>
    </li>

  8. </ul>

The bold line is the only line you will have to change to make the rater show what current rating it has. I decided to include it as an in-tag style because its easier to accomplish with server-side scripting. The other solution that I had was to id every current-rating list element and then in an inline stylesheet I declared all the values there. It’s your call.

The only thing you’ll need here is a little math. Remember, each star is 30 pixels wide. So, I’m sure that you will have a server-side script running to determine the average rating for the current item/article, so lets just pretend that the script figured that the average rating was 3.5 stars. Here’s the solution:

Average Rating: 3.5
Each Star Width: 30px;
Set width to: 3.5 * 30 = 105px

So, in this case you will set the list element with a class of current-rating to a width of 105px. Thats it!

Here are some samples of two different rating systems I set up, each including the CSS and the XHTML code to accomplish it:

Want to know how to implement this system with PHP and a Database? Over at SLIM, there is a great tutorial written on just this article.

Comments

217 Comments

Pages:
  1. Andy said 2410 days ago

    Cheers alot People!

  2. sion said 2411 days ago

    i’ve put it inside a table… it don’t work correctly.
    The current rating is not shown, and the numbers 1,2,3,4,5 are shown.

    Any help?

  3. SvT said 2411 days ago

    tnx..

  4. Shafiq Rehman said 2413 days ago

    Hey! great stuff.

  5. baryk said 2415 days ago

    Thanks Rogie!

    overflow:hidden; did the trick!
    Now I have 75 x 15 star rating system working flowlessly.

    Cheers

  6. Rogie said 2418 days ago

    @Baryk: My bad, but you should try adding overflow:hidden; in the .star-rating li a CSS rules.

  7. baryk said 2418 days ago

    this is an excellent work, well done!

    just one thing. Can anyone help me to make the star smaller than 20px?
    Because it seems it does not work on IE if I make the stars anything smaller than 20px.

    Although works perfectly fine on firefox, IE completely messes up with the positioning of the stars so I can see 5 yellow stars and also the bottom edge of the 5 green stars at the same time.

    20×20 (or bigger) stars are slighly big for my liking so I really appreciate any help here.

    Thanks.

  8. henners said 2430 days ago

    hello again, I have now managed to do this dynamically with asp and msaccess. so i get the average star rating

  9. Yiğit said 2433 days ago

    Wonderful CSS, congrulagations. Thanks too.

  10. Munteanu Alex said 2433 days ago

    Incredible work, been trying on my own for several days and when i finnaly did something i found this baby, 10x a lot, great piece of css coding

  11. henners said 2436 days ago

    one thing is though, i cant get the “current-rating” part of the css to work, it just shows the white background

  12. henners said 2436 days ago

    great code. im redesigning my site and wanted a star rating thing for some videos. Ill probably do this using asp so that the information is submitted to the same table as the one that contains my video information by calling up the current star rating and the no of ratings and then working out the new average.

  13. ShinyChrome said 2438 days ago

    I have to say that you make this look easy! ;)

  14. Tom Robbrecht said 2439 days ago

    Very useful article, thanks !
    Hope you don’t mind me implementing this on my site.
    Only one problem though : I can’t seem to get the stars to float fully to the right of a bounding correctly in IE6. The usual text-align workaround breaks the rater. I’m stuped.
    Any useful pointers ? Anyone ?

    Cheers,
    Tom.

  15. Erika said 2447 days ago

    This is so cool! Thanks ;-)

  16. igvita.com said 2457 days ago

    Rails 4-State Ajax & CSS Star Rating…

    Dafe Naffis just recently posted a how-to for Ruby on Rails Ajax & CSS Star Rating System on his blog. Funny enough, I implemented an almost identical equivalent just a few days earlier for another project with some minor differences. I also u…

  17. Eivind said 2458 days ago

    Thank you for a very nice solution. Still some work left, but I have implemented this on my site using AJAX and made it work with ASP.

    Since my site as a “promotion site” for CSS web sites and solutions I have of course pointed a link to this solution.

  18. bongoman said 2462 days ago

    Ooops, I lost the tags in my comments above.

    Anyway, you’ll see what I mean – the li tag is closed prematurely so the width isn’t declared validly.

  19. bongoman said 2462 days ago

    There’s a small typo on your example #2 page (25 x 125px) — this line:

    style=’width:105px;’ Currently 3.5/5 Stars.

    should be:

    Currently 3.5/5 Stars.

  20. mayk said 2464 days ago

    Thank you so much.

  21. cheqbxywa sdnp said 2465 days ago

    pqcyska ztrdquole ruqvm rhbqi zfconpurm qelkw ungslh http://www.psycjekan.mjdwl.com

  22. wega dywie said 2465 days ago

    nuwhqvo lpewx kgcpyhfd hnqpdtrjm bqycjldk venhdkafs aogn

  23. ryan masuga said 2472 days ago

    Hi, I just greatly updated the script I had over at masuga.com (as referenced just a couple posts up). It’s now pretty much unobtrusive, and will still work even with Javascript disabled. The is much more detailed documentation as well. Stop on by! AJAX rating bar script at masugadesign. Thanks.

  24. Andy said 2483 days ago

    So, what’s the word on IE compatability? I can’t seem to get it to work. My blog, looks great in FF (as far as the star rating system) but looks completely wrong in IE once an entry has been voted on. Suggestions? Thanks!

    -Andy

  25. DrKaOs said 2487 days ago

    Hi sexydave, could you send me the download link?

    For all users, masuga.com created an ajax rating script based on komomedias rating system: http://www.masuga.com/thelab/ajaxrate/

    Bye!!

  26. jon said 2489 days ago

    hey sexydave,
    couldn’t find any email to contact you, so could you either email your version to me (mollasadra[at]hotmail.com) or just put a url somewhere.
    would really appreciate it.

  27. Keral said 2490 days ago

    Well I tried, tried and tried.

    But this is giving some error in java script.

  28. Michel said 2494 days ago

    Thank you so much.

  29. Anonymous said 2495 days ago

    CSS Star Rating System…

    This CSS tutorial covers the creation of a 5-star rating system using only CSS and a list of links. Uses just one image, css, and html!…

  30. XeNTaR said 2499 days ago

    To stop it from going to the top of the page because of the anchor ‘#’ in the href, you can just add a onclick=”return false;”in the tag.
    I used that trick on my website too and works perfectly!

  31. octavez said 2506 days ago

    What do you think of that?
    http://dev.wp-plugins.org/wiki/wp-postratings

  32. Steve Richert said 2508 days ago

    Hi & thanks for the great tutorial. I love the clean mark-up and no need for javascript. Looks great, too. I wonder if you mind that I yank your star graphic for an application of mine.

    Anyway, I’ve run into a snag with this little gem that has me stumped. I’ve built a test page that displays the rating system correctly. However, when I take the exact block of HTML and the exact CSS and dump them into an existing page of mine, it breaks. The green hover-stars appear beneath the gold stars. This disables all of the star buttons beneath the current rating. How annoying!

    This only happens in FireFox. I have version 1.5.0.4 and I am on a Mac.

    I made sure that in my working test page, I included all of the exact same additional styles that would be included in the end-product page.

    THIS JUST IN:
    I removed the from the nested divs where it’s supposed to live. And it works.
    But I need to return it from whence it came. What would be causing this z-index problem?

    Thanks a ton!

  33. ayhan said 2517 days ago

    thanx. nice job. i m going to use it with xajax.

  34. Ron Z. said 2524 days ago

    sorry about the previous post of the link…here it is again:

    http://www.planjam.com/date.php

  35. Ron Z. said 2524 days ago

    Implemented the star ratings on my website, [url=http://www.planjam.com/date.php]PlanJam.com[/url]. I am using MySQL and PHP to do the rest.

    Thanks!

  36. Ashish Gupta said 2524 days ago

    Great Great work. I had read the 1st article and was waiting for something like this after that where 1/2 star or something like that can be seen. Keep up the good work !!!!!

  37. dcaunt said 2526 days ago

    Firstly, thanks for this great rating script.

    Secondly, to the people commenting who implemented the actual rating features – why have you made your javascript/ajax solutions incompatible to users with javascript disabled ?!

    Surely it would be smarter to define a link to a php script to set the rating, and then if AJAX is supported modify the links via DOM to use call javascript instead of using the php script.

  38. marco said 2527 days ago

    hello! this is exactely what i was looking for the last few hours!! i dont know too much about php. so could somebody email me the finished thing? my mail is mail@studentenkueche.ch .
    thanx a lot!!

  39. Philip Pryce said 2534 days ago

    If the default rating isnt positioned correctly over the rating stars just add “left:0;” to the class “li.current-rating”. should position correctly then.

  40. matiasjajaja said 2536 days ago

    thanks !

  41. sexydave said 2540 days ago

    hi again,

    I finally got some time to do my changes… If someone want it i could put an url here no problem. It’s great to put is own mods to a already great script.

    Mainly the front-end haven’t changed much but the backend got a face lift! The main addon i done is the cookie-time ability. Now the script allow an ip to vote on an id only once for a certain period of time (‘cookietime’ and ‘multiple votes per ip’ are custom of course).

    Also, i didn’t like to unprotect certain part of the scripts (well at least the MySQL connexion values) so i redo that part… and after i redo the coding to use a Mysql class to clear the codes.

    The mods:
    1. Adding a Simple MySQL class to clean the code.
    2. Adding Functions abbilities to clean the code.
    3. Adding a config file, so now all setup values are in one place.
    4. Recode the scripts to fit with the new Classes and Functions.
    5. Redone the architectural of the script to protect the private php files.
    6. Display rating are in a string (config file) instead of in the code.
    7. Adding a value in the config file to allow multiple voting per rating.
    8. Redo the mysql table of the ratings (delete unused fields).
    9. Adding a cookie function (in mySQL table). The script now keep only valid IPs.
    10. Adding a cookie time value in the config.

    Cheer evryone! :)

  42. Luke said 2544 days ago

    Wow great article mate, and the original one as well, really helped me understand a few things I was a bit stuck with on CSS. Thanks a lot!

  43. sexydave said 2547 days ago

    hi,

    Great tutorial with AJAX function! I really like this script so if you don’t mind making some new stuff, i think everone here will be happy, and i’m the first. :)

    The only thing i can think of is that the dbase will get huge overtime… and there’s no time setting on IP’s voting… maybe if i can figure it out it could be great to add it.

    great work!

  44. stevos said 2551 days ago

    good stuff – anyone know of a ruby on rails implementation of this?

  45. Rogie said 2559 days ago

    lavag, I think ssin took out the ‘#’ in the anchor tag’s href and everything worked.

  46. lavag said 2559 days ago

    ssin how do you stop the page from jumping?
    It’s not clear from your post.

    thanks

    ps. fantastic tut by the way!!

  47. selim said 2565 days ago

    yes very interesting :D

  48. Sumeet Wadhwa said 2565 days ago

    interesting article ! thanks…

  49. ssin said 2566 days ago

    Doh! the html got messed up.

  50. ssin said 2566 days ago

    Thanks! the # was the problem. Instead of # i put in javascript:sndReq(‘1′,’1′,’ip’) and got rid of the onclick function.

    So instead of using…
    ‘)”>1

    ..i used..

    ‘)\” title=’1 star out of 5′ class=’one-star’>1

    Hope this helps other people too!

Sorry, the comment form is closed at this time.