UPDATE!! A plugin is now available for this tutorial that includes more features, like a new theme and number of stars options! Right Here >>> elistar rating plugin
Back to the Original Post:
Here is a nice little rating effect. This does not include the PHP, it is only the JavaScript, HTML, CSS, and Images. If you like this, I do have the PHP script that I created, but will not support, and I threw together quite quickly. But, what the heck, back to this post now.
Look below and you can see what will be created by the time we are done with this project.
Skip to full source code || Download Source in .zip
What we start with is one HTML file, JQUERY library, star_rating.js (contains all the effects), and the image folder with some images.
First let’s take a look at the file structure.

Right now I contain all the CSS in the html file, out of shear laziness, and so you don’t have an extra file with a small amount of CSS in it.
So let’s talk about the html.
Everything except the hidden form field that contains the final rating selected is contained within the rating_cont div.
Inside the main rating_cont div is three more divs.
<div id="rating_cont">
<div id="rating_btns"></div>
<div id="rating_on" > </div>
<div id="rated"></div>
</div>
<input type="hidden" id="rating_output" name="rating_output" value="not rated" />Now that we have the main divs setup, let’s add some of the style so we can see what we are working with.
We will add the following CSS to the rating_cont, our main div.
#rating_cont { background: #1E1D1C url(images/rating_background.jpg) top left no-repeat; border: 1px solid #F9BA0D; width: 140px; height: 23px; text-align: left; margin-left: 6px;}This puts the background image of the stars ‘off’ and creates our height, width, border, and background for our main container.
Next, let’s create the CSS and html for the rating_btns div.
The rating_btns div will have an unordered list with the actual ratings in it.
Look below.
<ul>
<li>0.5</li>
<li>1.0</li>
<li>1.5</li>
<li>2.0</li>
<li>2.5</li>
<li>3.0</li>
<li>3.5</li>
<li>4.0</li>
<li>4.5</li>
<li>5.0</li>
</ul>If you’re doing the code step by step, I’m sure you noticed that this looks pretty ugly right now. Let’s add the CSS to the rating_btns div and the ul we have.
The rating_btns div needs to be above the rating_on div that we will create next, so we will give it a relative positioning and a z-index of 100. We also add the height and width to define the container of our <li> links.
Inside the rating_btns div is our <ul> and it’s <li>. We do not want our <ul> or our <li> to have any margin or padding. The <li> needs to be 14px wide. Guess why. 14 x 10 = 140! Yup, you got it. That is the width of our container, amazing, I know. We are going to float them left, give them a block display so they don’t go over each other, and last but not least, change the font display. We will change the font to 1px, and the same color as the background. I’m sure you’re asking; why not just have them empty and not have any text in there at all? Well, we will use this text to tell our JQuery script what you hovered over.
Here is the CSS for this.
#rating_btns { position: relative; z-index: 100; width: 140px; height: 21px;}
#rating_btns ul, #rating_btns li { padding: 0; margin: 0; }
#rating_btns li { float: left; width: 14px; height: 21px; display: block; font-size: 1px; cursor: pointer; color: #1E1D1C; }Next, look at our rating_on div. Just as it says, it is our div that contains our stars that are “ON”. We use a quite unique way of doing this. We give it a background image of the “on” stars, but change it’s width based upon what we hover over. That’s the reason we had to give the rating_btns a relative positioning with a z-index, and this div we will also give a relative positioning, but a z-index of 50. We will also set the width to 0px initially, so it doesn’t show before we hover over it.
Here is the HTML for this:
#rating_on { background: url(images/rating_onbackground.jpg) top left no-repeat; width: 0px; height: 21px; position: relative; z-index: 50; top: -21px; }
<div id="rating_on" > </div>On to our last div, our rating div, this contains three smaller divs that act as cells, one containing the selected rating, another containing the image of the stars, and the last one containing our edit link.
I still haven’t gotten to the JQuery yet, so I will just show you the CSS, and HTML for this.
#rated { display: none; width: 138px; padding: 3px 0px 3px 2px; height: 23px; background-color: #1E1D1C; height: 17px;font-size: 11px;color: #FFC910;}
#rated div { display: block; float: left; }
#rating { font-size: 11px; font-family: Arial, Helvetica, sans-serif; color: #FFC910; padding-left: 3px; width: 22px; }
#small_stars { height: 11px; width: 69px; background-image: url(images/stars_small_sprite.jpg); background-position: 0px -11px; font-size:1px; line-height: 11px; margin-top:3px; }
#rate_edit { line-height: 17px; font-size: 11px; font-family: Arial, Helvetica, sans-serif; color: #FFF; padding-left: 9px; cursor: pointer; }
#rate_edit:hover { text-decoration: underline; }
<div id="rated">
<div id="rating" style="height: 17px; line-height: 17px;">not rated</div>
<div> – </div>
<div id="small_stars"> </div>
<div id="rate_edit">edit</div>
</div>Since this will be used to send a rating from a form, we will add a hidden form field to be sent. This will be updated from JQuery.
<input type="hidden" id="rating_output" name="rating_output" value="not rated" />Ok, on to the fun stuff, the JQuery.
This will have a total of six functions, NOT including the document.ready function.
With JQuery we need to surround it’s functions with $(document).ready(function()).
In saying that, keep that in mind when you look at the source code. If you don’t know what I am talking about, check out the full source code at the end of this post, or the downloadable source code.
1. rateWidth function
This function accepts the rating variable from our JQuery functions, converts it to an Integer, uses a switch statement to determine the width value, then returns the width to make our rating_on div show the stars. (shows the stars).
function rateWidth($rating){
$rating = parseFloat($rating);
switch ($rating){
case 0.5: $width = "14px"; break;
case 1.0: $width = "28px"; break;
case 1.5: $width = "42px"; break;
case 2.0: $width = "56px"; break;
case 2.5: $width = "70px"; break;
case 3.0: $width = "84px"; break;
case 3.5: $width = "98px"; break;
case 4.0: $width = "112px"; break;
case 4.5: $width = "126px"; break;
case 5.0: $width = "140px"; break;
default: $width = "84px";
}
return $width;
}2. starSprite function
I used two different methods for creating the stars. One uses less HTML, and one uses more. For the small stars that show up when you make a rating, I wanted to use less HTML and used the sprite method to show the rating. But it does the same thing as the rateWidth but determines the background positioning based on the rating provided.
function starSprite($rating){
$rating = parseFloat($rating);
switch ($rating){
case 0.5: $pos = "-11px"; break;
case 1.0: $pos = "-22px"; break;
case 1.5: $pos = "-33px"; break;
case 2.0: $pos = "-44px"; break;
case 2.5: $pos = "-55px"; break;
case 3.0: $pos = "-66px"; break;
case 3.5: $pos = "-77px"; break;
case 4.0: $pos = "-88px"; break;
case 4.5: $pos = "-99px"; break;
case 5.0: $pos = "-110px"; break;
default: $pos = "-77px";
}
return $pos;
}3. hover function *JQuery
The hover function will detect the cursor hovering over our <li>’s and the value of it and then send the value to the rateWidth function to get our width. It then assigns the width to the #rating_on div.
$('#rating_btns li').hover(function(){
$rating = $(this).text();
$('#rating_on').css('width', rateWidth($rating));
});4. mouseout function
The mouseout function does just that, tells what stars should be showing on mouseout. But we do not want the stars to be reset every time we go off the stars, especially if we already selected a rating. So we grab the value of our #rating div and if it is “not rated” we set our width to 0px but if it doesn’t equal “not rated” we set the width of it’s set value. This way if you have selected a rating it defaults back to it when you mouseout.
$('#rating_btns li').mouseout(function(){
$rating = $('#rating').text();
if($rating == "not rated"){
$('#rating_on').css('width', "0px");
}
else{
$('#rating_on').css('width', rateWidth($rating));
}
});5. click function
This function has a little bit more going on than the other ones. When you click the <li> it first grabs the value of the clicked <li> assigns it to the #rating div, uses starSprite function to assign the background position for the #small_stars div, then hides the #rating_btns div, and the #rating_on div. Once hidden, it nicely fades in the #rated div.
$('#rating_btns li').click(function(){
$rating = $(this).text();
$('#rating').text($rating);
$('#rating_output').val($rating);
$pos = starSprite($rating);
$('#small_stars').css('background-position', "0px " + $pos );
$('#rating_btns').hide();
$('#rating_on').hide();
$('#rated').fadeIn();
});6. edit function
This function just hides the #rated div and fades in the two divs we just hid. The #rating_div and the #rating_btns div.
$('#rate_edit').click(function(){
$('#rated').hide();
$('#rating_btns').fadeIn();
$('#rating_on').fadeIn();
});Bam… we’re done.
Here is the completed code for your viewing pleasure.
HTML (star_rating.html) -
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JQuery-Star Comment Rating</title>
<script type="text/javascript" src="js/jquery/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/star_rating.js"></script>
<style type="text/css">
#rating_cont { background: #1E1D1C url(images/rating_background.jpg) top left no-repeat; border: 1px solid #F9BA0D; width: 140px; height: 23px; text-align: left; margin-left: 6px;}
#rating_on { background: url(images/rating_onbackground.jpg) top left no-repeat; width: 0px; height: 21px; position: relative; z-index: 50; top: -21px; }
#rated { display: none; width: 138px; padding: 3px 0px 3px 2px; height: 23px; background-color: #1E1D1C; height: 17px;font-size: 11px;color: #FFC910;}
#rated div { display: block; float: left; }
#rating { font-size: 11px; font-family: Arial, Helvetica, sans-serif; color: #FFC910; padding-left: 3px; width: 22px; }
#small_stars { height: 11px; width: 69px; background-image: url(images/stars_small_sprite.jpg); background-position: 0px -11px; font-size:1px; line-height: 11px; margin-top:3px; }
#rate_edit { line-height: 17px; font-size: 11px; font-family: Arial, Helvetica, sans-serif; color: #FFF; padding-left: 9px; cursor: pointer; }
#rate_edit:hover { text-decoration: underline; }
#rating_btns { position: relative; z-index: 100; width: 140px; height: 21px;}
#rating_btns ul, #rating_btns li { padding: 0; margin: 0; }
#rating_btns li { float: left; width: 14px; height: 21px; display: block; font-size: 1px; cursor: pointer; color: #1E1D1C;
}
</style>
</head>
<body>
<div id="rating_cont">
<div id="rating_btns">
<ul>
<li>0.5</li>
<li>1.0</li>
<li>1.5</li>
<li>2.0</li>
<li>2.5</li>
<li>3.0</li>
<li>3.5</li>
<li>4.0</li>
<li>4.5</li>
<li>5.0</li>
</ul>
</div>
<div id="rating_on" > </div>
<div id="rated">
<div id="rating" style="height: 17px; line-height: 17px;">not rated</div>
<div> – </div>
<div id="small_stars"> </div>
<div id="rate_edit">edit</div>
</div>
</div>
<input type="hidden" id="rating_output" name="rating_output" />
</body>
</html>JQuery/JavaScript (star_rating.js) -
/*
* Written by eligeske
* downloaded from eligeske.com
* have fun. nerd.
*/
$(document).ready(function(){
// hover
$('#rating_btns li').hover(function(){
$rating = $(this).text();
$('#rating_on').css('width', rateWidth($rating));
});
// mouseout
$('#rating_btns li').mouseout(function(){
$rating = $('#rating').text();
if($rating == "not rated"){
$('#rating_on').css('width', "0px");
}
else{
$('#rating_on').css('width', rateWidth($rating));
}
});
//click
$('#rating_btns li').click(function(){
$rating = $(this).text();
$('#rating').text($rating);
$('#rating_output').val($rating);
$pos = starSprite($rating);
$('#small_stars').css('background-position', "0px " + $pos );
$('#rating_btns').hide();
$('#rating_on').hide();
$('#rated').fadeIn();
});
//edit
$('#rate_edit').click(function(){
$('#rated').hide();
$('#rating_btns').fadeIn();
$('#rating_on').fadeIn();
});
function rateWidth($rating){
$rating = parseFloat($rating);
switch ($rating){
case 0.5: $width = "14px"; break;
case 1.0: $width = "28px"; break;
case 1.5: $width = "42px"; break;
case 2.0: $width = "56px"; break;
case 2.5: $width = "70px"; break;
case 3.0: $width = "84px"; break;
case 3.5: $width = "98px"; break;
case 4.0: $width = "112px"; break;
case 4.5: $width = "126px"; break;
case 5.0: $width = "140px"; break;
default: $width = "84px";
}
return $width;
}
function starSprite($rating){
$rating = parseFloat($rating);
switch ($rating){
case 0.5: $pos = "-11px"; break;
case 1.0: $pos = "-22px"; break;
case 1.5: $pos = "-33px"; break;
case 2.0: $pos = "-44px"; break;
case 2.5: $pos = "-55px"; break;
case 3.0: $pos = "-66px"; break;
case 3.5: $pos = "-77px"; break;
case 4.0: $pos = "-88px"; break;
case 4.5: $pos = "-99px"; break;
case 5.0: $pos = "-110px"; break;
default: $pos = "-77px";
}
return $pos;
}
});I hope it works for you all. If you have any questions feel free to leave a comment.
UPDATE!! A plugin is now available for this tutorial that includes more features read more...
When running a site with a boat load of javascript, you may want to run a script read more...
Download Plugin THEMES: theme-lighttheme-dark<link href="{{ path to js read more...
Greetings All! Since everyone was digging the Star Comment Rating I decided that read more...
How often do you work with tables? I work with them quite a bit and styling t read more...

Copyright © 2012 Eli Geske. All Rights Reserved

too longwell done! thanks for sharing!What makes it as lengthy as it appears is the rated box fade-in effect. If you need a shorter one you can take out the starSprite function, .click and the “edit”.click. Here is the edited Jquery that would only be the roll over effect:$(document).ready(function(){
// hover
$(‘#rating_btns li’).hover(function(){
$rating = $(this).text();
$(‘#rating_on’).css(‘width’, rateWidth($rating));
});
// mouseout
$(‘#rating_btns li’).mouseout(function(){
$rating = $(‘#rating’).text();
if ($rating == “not rated”) {
$(‘#rating_on’).css(‘width’, “0px”);
}
else {
$(‘#rating_on’).css(‘width’, rateWidth($rating));
}
});
//click
$(‘#rating_btns li’).click(function(){
$rating = $(this).text();
$(‘#rating’).text($rating);
$(‘#rating_output’).val($rating);
});
function rateWidth($rating){
$rating = parseFloat($rating);
switch ($rating) {
case 0.5: $width = “14px”;break;
case 1.0:$width = “28px”;break;
case 1.5:$width = “42px”; break;
case 2.0:$width = “56px”;break;
case 2.5:$width = “70px”; break;
case 3.0:$width = “84px”; break;
case 3.5:$width = “98px”; break;
case 4.0: $width = “112px”;break;
case 4.5:$width = “126px”;break;
case 5.0:$width = “140px”;break;
default:$width = “84px”;
}
return $width;
}
});
Nice but when you reload the page it shows like you didn’t rate. So I do not see any purpose of this.
Hey Strawberry,This was created only to make a rating. You would need to add some server side scripting to this in order to make the rating stay. When creating a rating system you need to get the average of all the ratings on a particular item or post. Usually this is done by allowing the user to select which rating they want, then send it to the database, and have the average reappear.
Let me know a little bit about your skills so I can better assist you.
Are you a web designer or a programmer?
Thanks for the write-up. It works on firefox, but I notice that your page doesn’t render on chrome.That’s a cool code!Love it!!!!
You are great!!!!…i see it in every word……..keep goingWell its for every one ……… from the basic….i just installed it and was having trouble ..with file structure …you saved my day…thanks!!!!!Glad you found it helpful! Tis the season to be jolly!
Thanks for sharing. This is really useful.This looks great,just what I need. But how would I pass the voted value to php since the page doesn’t seem to send a form? Also, could I build the chosen rating based on stored valuesKakubei,There are several different ways you could pass the vote into php. I’ll give you a couple examples.
1. HTML form -
<input type=”hidden” id=”rating_output” name=”rating_output” value=”not rated” />
<input type=”submit” />
</form> .
Note: The hidden input field that you created with the tutorial will have the value of the rating after they click it, so when they submit the form it will send the rating to your php file. Test it by changing the type=”hidden” to type=”text” and you can see how it works.
-
2. AJAX (with JQuery of course)
$rating = $(‘#rating_output’).val();
$.post($url, {
rating: $rating
}, function(data){
$(‘#rate_edit’).remove(); // hide the edit
});
Note: Put this right inside your $(‘#rating_btns li’).click(function(){ //here });
Also, notice inside the ajax function the .remove, this will remove the “edit” so they cannot send multiple ratings.
– Let me know if this has helped you at all. As far as the build the rating on stored values, explain what you are trying to do a little more on that and I ‘ll see what I can do.
Eli
thanks a lot !My Pleasure!very nice !!!!!!!Note that in the Opera browser in element <li> is visible text value (0.5, 1, 1.5 … etc). To prevent this bug you have to set in css style – font-size: 0px; for element #rating_btns li.Hello webmaster I like your post
thanks a lot…very helpful tutorial…..:)Thanks for the update on that ZO_h,I should have checked all browsers with it. For those of you who have problems checking out cross browser compatibility, I found an awesome way that some of you may know of. http://www.spoon.net/browsers
Null problem!I’m using part of your code in my site (crete.pl). I combine this with php, cookie, mysql and smarty template. Works very fine.
Many thanks for your work! Great work!!
very helpful tutorial
THANK YOU!Pingback: jQuery « Future Technology
Pingback: 20 Must Read JQuery Tutorials for Web Developers | Gadgets World
Hello!What if the client changes the html so that in the list item, he/she types <li>999<li> ? You should add delimiters in server-side scripting i think?
Pingback: 20 Must Read JQuery Tutorials for Web Developers | Gadgets World
Server side validation is always a must! Relying on the client side to do validation makes it pretty and fast for the user, but ultimately for your data’s safety you MUST ALWAYS do server side validation.Pingback: 20 Must Read JQuery Tutorials for Web Developers | Gadgets World
heah that’s so greatthanks for explaining
Hi,Great script and it doesn’t interfere with my other jQuery scripts on the page. Took me a while to find one.
Question: Is there a way I can get it to default to a selection, in case the user makes a mistake on the form and I need to go back. i.e. defaults to 4 stars but they can then change their selection or maybe even turn off all the stars.
Thanks, Adam
Ya, that shouldn’t be a problem at all.Tell me step by step on how you are using it, or even better, show me an online example that your working on, if you have the ability.
Awesome!http://www.mcloveit.com/add?query=JQuery+%E2ໄ໑+Star+Comment+Rating&action=Add
Just click on your rating script or the one I modified for price and hit add without typing a email or password. Since the user didn’t log in, they are redirected back and I need to set the default value that was originally posted (now a session VAR).
Woops. Didn’t like that type of dash in the link:http://www.mcloveit.com/add?query=JQuery+-+Star+Comment+Rating&action=Add
Thanks, Adam
Eli is great!!! He helped me set a default value. Here is what you need to do:Put your default value in the rating div and the hidden field:
<div id=”rating”>2</div>
<input type=”hidden” id=”rating_output” name=”rating_output” value=”2″ />
Note: you would place your session variable where the 2 is located i.e. <? echo $default_rating; ?>
Add the following above the //hover section in the .js file:
// set default value
$(‘#rating_on’).css(‘width’, rateWidth($(‘#rating_output’).val()));
In the rateWidth function, set the default to 0px:
default: $width = “0px”;
That should do it. Again, thank you Eli for coming up with this great script. I searched a long time.
substitute the &ා with a poundThis was great. I’ve worked on the backend stuff for ages, but now I’m picking up the js/JQuery and css as well. This is one of the best explanations I’ve seen on why you’re doing things the way you are. Kudos.glad to be of some help!i just learned this today and i wish i did along time a gothanks
this code working well so far but i’m trying to preload the values from database at start, i was able to use your additional ajax code to send to database, now i just want it to load from database at first showing the stored value in database. can you helpAre you using php?yes i am using php and mysql<input id=”defaultValue” type=”hidden” value=”<?php echo $loadedValue; ?>” />If you add a hidden input field and give it the value you have in your database as an initial value, then you can check it with jquery on page load to set the current rating.
Let me know if you have any questions on how to do this, I’ll be glad to help.
if you could, but you can take your time, would be nice for what im looking for. what would i change in the html and jquery above to load from my database i see how you did this above<input id=?defaultValue? type=?hidden? value=?<?php echo $loadedValue; ?>? />
but i dont know where to put that.
and you do not have a setup like this for one with 10 stars do you?
this worked out for me and had the 10 stars, http://orkans-tmp.22web.net/star_rating/index.html#main-menu=1Thanks for sharing CT,I just added a new tutorial on creating your own animated JQuery Bar Chart, with only JQuery, CSS, and Simple HTML.
Can we make it without PHP?can you give your email?Hi kartik,The star comment rating is all jquery, CSS and HTML. But you will need some server side script to do any database writing and retrieval.
Hey !I just absolutely love your rating system and would love to implement in on a website I have under development for a client. However, I would like it to average the user ratings and save this perhaps to a database ? Then I want this to be retrieved whenever a user visits the webpage for a image or item or something. Can you help me with that ?
I’m a programmer (HTML,CSS,JQuery, ASP.NET – C# and a bit of php).
- Thanks
Hi Michael,There are many different ways to implement the server side portion of a rating system.
Here is a couple things to keep in mind:
1. Keeping the same person from submitting multiple ratings on the same product.
- allow only logged in users to submit rating.
- track ratings by IP, which isn’t full proof but does the job.
2. Is what is to be rated database driven itself? If so, then you would just add an additional table with a timestamp, rating, who rated it, and product id (or id of what you’re rating)
3. Will need to expose some type of webservice or a page to catch the postback or get parameters from Ajax call when rating is clicked.
What program language will you be using?
Good idea and great UI. I took an hour and ported your idea to a jQuery plugin. I actually needed something like this for one of my project.Sample (Check the source for details)
http_://www.bloice.me/star-rating/starplugin.html- No need anymore to prebuild the html ul /li. Just put a div and call $(‘.rateMe’).stars();
- you can set the “rel” attribute to the initial “score” and it will prepare it when the page is rendered.
- Works with unlimited of components on the same page
- Customizable callbacks, you can set the click and cancel callabcks in the options
i am using in one of the project. i need to show the total average on the page loading.please give suggestion“14 x 100 = 140!”O RLY?
Lol. That post is almost 3 years old and you are the first one who caught that.