Reputation: 2853
I am currently working on implementing a star-rating widget. Which needs to make use of a sprite file, which looks as the following
I have my html structured as following
HTML
<span id="star-ratings" class="containers">
<span id="ratings"></span>
</span>
I have the following CSS, which is where i am unsure of in terms of displaying the stars
#star-ratings, #ratings{
background:url(../images/star-sprite.png) 0 15.8px repeat-x;
display: block;
width: 78px;
height: 14px;
}
To further explain my thought process, i am passing down a rating value which can range from 0-5 through my javascript and then calculating the final width size and applying it to the inner span.
Currently i am trying to display the initial start, which is the empty star. But instead i see all the stars on my page.
Upvotes: 0
Views: 496
Reputation: 5104
Let's use the image
you provided in the example. The image have 80px width (actually its 79px but i'm rounding up), 14px height and 5 states: 0%, 25%, 50%, 75% and 100%.
To use the image as a sprite, we will create a base class called .star
and assign the height of the image (14px) and the width of a single state, which would be 16px (80px / 5 states).
The default state will be the first one in the sprite (0%). Afterwards, we create an extra CSS for each aditional state: 25%, 50%, 75% and 100%.
Each class will have a different value for the background-position
attribute, based on the state width.
Here is an example using the image provided by the user as a sprite.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.rating {
margin: 25px;
}
.rating label {
font-weight: bold;
display: block;
}
.star {
display: inline-block;
width: 16px;
height: 14px;
background-image: url('https://i.sstatic.net/ZSMMj.png');
background-repeat: none;
}
.star-25 {
background-position: -16px 0;
}
.star-50 {
background-position: -32px 0;
}
.star-75 {
background-position: -48px 0;
}
.star-100 {
background-position: -64px 0;
}
</style>
</head>
<body>
<div class="rating">
<label>1/5 (20%)</label>
<span class="star star-100"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
</div>
<div class="rating">
<label>4/5 (80%)</label>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star"></span>
</div>
<div class="rating">
<label>8/10 (80%)</label>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star star-100"></span>
<span class="star"></span>
<span class="star"></span>
</div>
</body>
</html>
Here is another example using only CSS (no images), for additional studies purposes. Based on Accessible star rating widget with pure CSS, provided by the user connexo
in the comments.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<style type="text/css">
body {
margin: 25px;
}
.center {
padding: 10px 0;
}
input[type=number] {
font-size: 22px;
padding: 5px;
width: 50px;
}
.star-rating {
display: inline-block;
}
.star {
font-size: 30px;
}
.star:before {
content: '★';
color: #ddd;
text-shadow: 2px 2px #bbb;
}
.star-rating[data-value="1"] .star:nth-child(-n + 1):before,
.star-rating[data-value="2"] .star:nth-child(-n + 2):before,
.star-rating[data-value="3"] .star:nth-child(-n + 3):before,
.star-rating[data-value="4"] .star:nth-child(-n + 4):before,
.star-rating[data-value="5"] .star:nth-child(-n + 5):before,
.star-rating[data-value="6"] .star:nth-child(-n + 6):before,
.star-rating[data-value="7"] .star:nth-child(-n + 7):before,
.star-rating[data-value="8"] .star:nth-child(-n + 8):before,
.star-rating[data-value="9"] .star:nth-child(-n + 9):before,
.star-rating[data-value="10"] .star:nth-child(-n + 10):before {
color: #fff455;
text-shadow: 2px 2px #c3bb41;
}
</style>
</head>
<body>
<div class="center">
<input type="number" value="0" min="0" max="3" class="star-control" data-target="#star-1">
<div id="star-1" class="star-rating" data-value="0">
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
</div>
</div>
<div class="center">
<input type="number" value="0" min="0" max="5" class="star-control" data-target="#star-2">
<div id="star-2" class="star-rating" data-value="0">
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
</div>
</div>
<div class="center">
<input type="number" value="0" min="0" max="10" class="star-control" data-target="#star-3">
<div id="star-3" class="star-rating" data-value="0">
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
<span class="star"></span>
</div>
</div>
<script type="text/javascript">
function onStarControlChange() {
var $this = $(this),
value = $this.val(),
target = $this.data('target');
$(target).attr('data-value', value);
}
$('.star-control').on('change', onStarControlChange);
</script>
</body>
</html>
Upvotes: 2
Reputation: 32255
You have used the width for all the images combined while you need to define the width for that particular image. Modify the place of the internal images using background-position
#star-ratings,
#ratings {
background: url(https://i.sstatic.net/ZSMMj.png) 0 0 repeat-x;
display: block;
width: 14px; /* Modified */
height: 14px;
background-position: 0px;
}
.ratings1 {
background: url(https://i.sstatic.net/ZSMMj.png) 0 0 repeat-x;
display: block;
width: 14px;
height: 14px;
background-position: -16px;
}
First rating
<span id="star-ratings" class="containers">
<span id="ratings"></span>
</span>
Second rating
<span id="star-ratings" class="containers">
<span class="ratings1"></span>
</span>
Upvotes: 2