Need help with Star Sprite

I could use some help understanding how to create a Star Sprite for a Rating System on my website.

This past winter, I created my first Sprite image in Inkscape and then programmed it using PHP and CSS.

Unfortunately, that knowledge won’t really help me this time because in that case my sprite was a background image behind a Command Button and was intended to let people click on the star to toggle different states.

Now I just need a Star Sprite with 1 - 5 stars to show how a comment is rated.

This one will just be display-only, with no interactability. (Is that a word?!)

I’m not really sure where to begin as far as the HP and CSS, and creating a more complete sprite in Inkscape makes me nauseous. :frowning: :frowning: :frowning:

Help!!

Sincerely,

Debbie

Hi Debbie,

It all depends on what you are displaying exactly and what functions you expect them to have. If it is just 5 stars all the same colour then you don’t need a sprite as such as you could just use one image and repeat it. If on the other hand you are showing half stars and different coloured stars then you will need a sprite. If you also want hover effects you will need a more complicated sprite again.

Here’s one I did about 10 years ago but is a little complex. It uses [URL=“http://www.pmob.co.uk/temp/images/star-matrix.gif”]this sprite to achieve that effect.

If you don’t want hover effects then you only need the one single image unless you are displaying the off states of the star as well and then you could use a double sprite instead.

Hi Paul. (BTW, Happy Belated Birthday!) :slight_smile:

Before diving into this, let me clarify what I am doing, and then maybe you can help me figure out the best approach to take…

I just added the ability for members to rate Comments by other members.

Beneath each Comment is a drop-down where a member can do a one-time vote on said Comment. After submitting things, my PHP inserts that in the database and then calculates a new “Average Rating” for said Comment.

Right now my PHP is returning a decimal result with a text label (e.g. “4.3 Stars”) for the Average Rating, but I figure that having something visual is more likely to catch people’s attention.

In an earlier thread of mine, I asked How to show Stars?

What are your thoughts on that point?? :-/

At this point, I am leaning towards showing between 1 to 5 yellow stars to reflect my “Average Rating” calculation, although I am not sure what to do if the Average Rating = 4.3

As you probably know, I will not be using JavaScript, and for this problem, I don’t think I need anything fancy like hover effects. (Although feel free to disagree with me!)

I just need a visual representation of how good or bad other people feel a member’s Comment is.

It seems like a happy medium might be to create a sprite in 1/2 Star increments (e.g. 1/2 star, 1 star, 1 1/2 stars,…, 4 1/2 stars, 5 stars), and then have my PHP either round up or down the Average Rating and then pick which Star-strip to show.

So, for example, maybe my PHP would say that an Average Rating = 4.3 would display the “4 Star strip”, whereas an Average Rating = 4.6 would show the “4.5 Star strip”…

I’m going to shut up now and let you enlighten me (as always)!!! :lol:

Sincerely,

Debbie

Hi Debbie,

As I mentioned above you can do this with one simple star image and just hide parts of it to get the half stars.

Here’s an example showing that method.

The star image is inside a span and you just reduce the width of the span and set overflow to hidden to create whatever fractions you need. I set up 10 classes so you can go up at 10 percent a time.

No need for fancy sprites and the image itself provides some semantic meaning rather than an empty element with a background image.

But isn’t it better for load times to use a sprite?

Or if I don’t use a “stacked sprite” with different rows of stars, then wouldn’t it be better to make a strip of 5 stars and then show/hide accordingly?

BTW, the link in your earlier post doesn’t work…

I tried to do this on my own, but it isn’t working.

Here is some sample code…


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<style>
		#boxComments{
				border: 1px solid #333;
				margin: 40px auto;
				max-width: 640px;
				padding: 10px 20px 60px 20px;
		}

		#boxComments .commentHeader{
				background-color: #e4e4e4;
				clear: both;
				margin: 0 -15px;
				padding: 0.4em 15px 0.2em;
				width: 100%;
				border-radius: 4px 4px 0 0;
				position: relative;
				text-align: left;
		}

		#boxComments .commentHeader span.commentStats{
				padding: 0 0 0 20px;
		}		

		/* NEW */
		#boxComments .commentHeader span.starRating{
				overflow: hidden;
				width: 10%;
		}

		#boxComments .commentHeader span.starRating img{
				margin: 0 0 -2px;
		}
		
		img{
				border: medium none;
				font: 12px/16px normal,Arial,Verdana,sans-serif;
		}
	</style>
</head>

<body>
	<div id="boxComments">
		<div class='commentWrapper'>
			<div class='commentHeader'>
				<span class='commentStats'>4.5 Stars</span>
				<span class='starRating'><img alt='Rating Star' src='/images/survey star - 02 ex.png'></span>
			</div>
		</div>
</body>
</html>

Sincerely,

Debbie

You are missing the point.:slight_smile:

I’m using one small image and its file size will be much smaller than a sprite with 5 images on it (5 times smaller in fact). You can call that image as many times as you like on the page because its the same image that is already loaded and in cache. It doesn’t load the same image 5 times!

Or if I don’t use a “stacked sprite” with different rows of stars, then wouldn’t it be better to make a strip of 5 stars and then show/hide accordingly?

No, for the reasons I mention above. You don’t need 5 images you need only one.

BTW, the link in your earlier post doesn’t work…

I fixed that earlier today thanks. :slight_smile:

Here is some sample code…


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<style>
		#boxComments{
				border: 1px solid #333;
				margin: 40px auto;
				max-width: 640px;
				padding: 10px 20px 60px 20px;
		}

		#boxComments .commentHeader{
				background-color: #e4e4e4;
				clear: both;
				margin: 0 -15px;
				padding: 0.4em 15px 0.2em;
				width: 100%;
				border-radius: 4px 4px 0 0;
				position: relative;
				text-align: left;
		}

		#boxComments .commentHeader span.commentStats{
				padding: 0 0 0 20px;
		}		

		/* NEW */
		#boxComments .commentHeader span.starRating{
				overflow: hidden;
				width: 10%;
		}

		#boxComments .commentHeader span.starRating img{
				margin: 0 0 -2px;
		}
		
		img{
				border: medium none;
				font: 12px/16px normal,Arial,Verdana,sans-serif;
		}
	</style>
</head>

<body>
	<div id="boxComments">
		<div class='commentWrapper'>
			<div class='commentHeader'>
				<span class='commentStats'>4.5 Stars</span>
				<span class='starRating'><img alt='Rating Star' src='/images/survey star - 02 ex.png'></span>
			</div>
		</div>
</body>
</html>

spans are inline elements and therefore cannot have dimensions set. You need to set the span to either display:block or display:inline-block or floated depending on your situation. If you want the span on the same line as the text then use display:inline-block.

I understand that, but I was still under the impression that it took more effort for your browser to load 5 smaller images than one slightly larger one.

My misunderstanding.

So dumb question, but how do I show the various number of star-images? (Can’t believe I am asking you that?!)

Maybe I could create a PHP loop that determine the “Avg Rating” and then displays the correct number of images?

Or do you just have 5 <img> for 5 stars?

Okay, I’ll check that out after responding. (But should I even study it now based on the advice here?)

Maybe this will work better?


	#boxComments .commentHeader span.starRating{
		display: inline-block;
		overflow: hidden;
		width: 10px;
	}

BTW, should I do the overflow/width thing on the set of collective stars (e.g. 5 stars needing to be 4 1/2), or should I set the style to only apply to the last star when I need 1/2??

Also, how reliable is that trick across devices and browsers?

Sincerely,

Debbie

Paul,

I tried to figure things out myself, and while I am close, my 1/2 star just isn’t right… :frowning:

Here is my code plus my star is attached at bottom…


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<style>
		#boxComments{
				border: 1px solid #333;
				margin: 40px auto;
				max-width: 640px;
				padding: 10px 20px 60px 20px;
		}

		#boxComments .commentHeader{
				background-color: #e4e4e4;
				clear: both;
				margin: 0 -15px;
				padding: 0.4em 15px 0.2em;
				width: 100%;
				border-radius: 4px 4px 0 0;
				position: relative;
				text-align: left;
		}

		#boxComments .commentHeader span.commentStats{
				padding: 0 0 0 20px;
		}		

		/* NEW */
		#boxComments .commentHeader div.commentRating{
			display: inline-block;
		}

		#boxComments .commentHeader div.commentRating img{
			margin: 0 0 -2px 0;
		}

		#boxComments .commentHeader div.commentRating span.halfStar{
			display: inline-block;
			overflow: hidden;
			width: 10px;
		}

		#boxComments .commentHeader div.commentRating span.halfStar img{
			margin: 0 0 -8px 0;
		}

	</style>
</head>

<body id="start">
	<div id="boxComments">
		<div class='commentWrapper'>
			<div class='commentHeader'>
				<span class='commentStats'>4.5 Stars</span>
				<div class='commentRating'>
					<img alt='Rating Star' src='/images/star_comment_rating.png'>
					<img alt='Rating Star' src='/images/star_comment_rating.png'>
					<img alt='Rating Star' src='/images/star_comment_rating.png'>
					<img alt='Rating Star' src='/images/star_comment_rating.png'>
					<span class='halfStar'>
						<img alt='Rating Star' src='/images/star_comment_rating.png'>
					</span>
				</div>
			</div>
		</div>
</body>
</html>

I used a negative margin on the 1/2-star to vertically align it with the full-stars, but doing so slightly chops off the bottom of the 1/2-star.

Also, if I check the rendering outside of FireFox, browsers like Opera and Chrome are not properly vertically aligning my 1/2-star.

My guess is that I once again did not understand what you were advising me to do…

Sincerely,

Debbie

I don’t know if this will help or hinder but here’s my take on it…

<!DOCTYPE html>
<html>
<head>
     <title>
          STARS RATING TEST
     </title>

     <style type="text/css">
     /*<![CDATA[*/

html,body {
	margin: 0;
	padding: 0;
	width: 100%;
	background: #111111;
}
.rate_bx{
     margin:200px auto;
     border-radius:5px;
     width:99px;
     height:23px;
     background-image:url("stars_rating_system_2.png");
     background-position:0px 24px;      /* 0 stars*/
     background-position:0px 48px;      /* .5 stars*/
     background-position:0px 71px;      /* 1 stars*/
     background-position:0px 92px;      /* 1.5 stars*/
     background-position:0px 113px;     /* 2 stars*/
     background-position:0px 134px;     /* 2.5 stars*/
     background-position:0px 155px;     /* 3 stars*/
     background-position:0px 178px;     /* 3.5 stars*/
     background-position:0px 199px;     /* 4 stars*/
     background-position:0px 220px;     /* 4.5 stars*/
     background-position:0px 241px;     /* 5 stars*/
}
     /*]]>*/
     </style>
</head>
<body>
     <div class="rate_bx"></div>
</body>
</html>

Hopefully you can expand on my idea…

I feel like posting an entry in this contest, so here goes…

Don’t know if this has any practical value on your site, but if the server can tell the page the percent of the width of the red star bar (70% = 3.5 stars), then this seems like a fairly easy, flexible display method. (This particular scheme renders a 0.0-10.0 graph quite nicely. :))


<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Stars for Debbie</title>
<!--
http://www.sitepoint.com/forums/showthread.php?1227201-Need-help-with-Star-Sprite
Aug 10, 2014, 13:47
DoubleDee
-->
    <style type="text/css">
.graystars {
    outline:1px solid #ccc;  /* for Demo */
    width:347px;
    height:71px;
    background:url('stars3.png') no-repeat 0 100%;
}
.redstars {
    width:0;
    overflow:hidden;
}
.redstars:before {
    content:"";
    display:block;
    width:347px;
    height:71px;
    background:url('stars3.png') no-repeat 0 0;
}
.post123 .redstars {width:70%;}    /* Try Me.  Enter the width of the red star bar in percent.  70% = 3.5 stars. */

    </style>
</head>
<body>

<div class="post123">
   <div class="graystars"><div class="redstars"></div></div>
</div>

</body>
</html>

I understand that, but I was still under the impression that it took more effort for your browser to load 5 smaller images than one slightly larger one.

The browsers isn’t loading 4 images its loading one image. You can repeat the same image a 1000 times but it will only load it once.

Also, how reliable is that trick across devices and browsers?

It’s not a trick - it’s just basic CSS :).

display:inline-block works from IE8+ and there are fixes if you need to support IE7 and under (or you could just float instead).

QUOTE=DoubleDee;5698356]Paul,

I tried to figure things out myself, and while I am close, my 1/2 star just isn’t right… :frowning:
[/QUOTE]

You didn’t take care of the vertical alignment properly.

You need CSS like this:


#boxComments {
	border: 1px solid #333;
	margin: 40px auto;
	max-width: 640px;
	padding: 10px 20px 60px 20px;
}
#boxComments .commentHeader {
	background-color: #e4e4e4;
	clear: both;
	margin: 0 -15px;
	padding: 0.4em 15px 0.2em;
	border-radius: 4px 4px 0 0;
	position: relative;
	text-align: left;
}
#boxComments .commentStats {
	padding: 0 0 0 5px;
}

#boxComments .commentRating,
.halfStar,
.halfStar img,
#boxComments .commentStats {
	display:inline-block;
	vertical-align:top;
}
.halfStar {
	overflow: hidden;
	width: 10px;
	height:18px;
}

No need for negative margins and other fixes as it all lines up nicely with the right rules. Your page lacks the structure of my example though and although my example is more html it is easier to use and easier to read.

Also keep your selectors as short as possible and as short as needed. There’s no need for this:


#boxComments .commentHeader div.commentRating span.halfStar {}

when this just does as well.


.halfStar{}

The browsers parse from right to left and so has to check the document for every selector in your rule rather than just once in my example.

Got it!

A-ha!

As an FYI, when I went to your original link all I saw was a finished example, and when I did View Source I got all of this Code Pen gibberish.

Your latest link comes up different, and I now can see your HTML and CSS. (Kind of hard to learn from examples when you can’t see the code…) :wink:

I have had this issue several times before on here, FWIW.

Anyways… Let me go over your code and see how the Master does things! (Hopefully I will “get it” this time?!) :slight_smile:

Sadly, there are lots of places in my code where that isn’t true.

My CSS has slowly become a real mess over the last 4 years, and if I ever get my website online, the next time around I probably need to start recoding my website from scratch when it comes to HTML and CSS… sigh

Then again, next time around, I hope to learn about Responsive Design and Mobile, so my current site may go another direction?! Fun fun!!

Sincerely,

Debbie

Yes you don’t want to view source on codepen as that is the application that is running the examples.:slight_smile:

If you go to the original link I gave then look down at the bottom of the screen there is a link that says “Edit Pen”. Click that link and you will be taken to the editor page where the css and html is all laid out for you to view and copy easily or indeed just amend and play with or fork to your own codepen. Codepen is free for the basic version and is a good place to host snippets and demos that you are working on. If you want code to be private then private then you need to pay a fee for a more enhanced version but for demos and examples its a great tool.