Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SVG based lightweight star rating system
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml" lang="en" xml:lang="en">
<head>
<meta charset="UTF-8">
<title>4.2 - 2.6</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<style type="text/css">
/* Empty part of stars */
.star-empty {
fill: #eae7de;
}
/* Partially filled stars using svg gradients */
.star-full {
fill: #fdd119;
}
.star-9 {
fill: url(#9Gradient);
}
.star-8 {
fill: url(#8Gradient);
}
.star-7 {
fill: url(#7Gradient);
}
.star-6 {
fill: url(#6Gradient);
}
.star-5 {
fill: url(#5Gradient);
}
.star-4 {
fill: url(#4Gradient);
}
.star-3 {
fill: url(#3Gradient);
}
.star-2 {
fill: url(#2Gradient);
}
.star-1 {
fill: url(#1Gradient);
}
.ratingStarSource {
position: absolute;
width: 0;
top: 0;
}
/* IE11 */
svg { display: inline-block; vertical-align: top; }
</style>
</head>
<body>
<svg aria-hidden="true" class="ratingStarSource" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="iconStarRating">
<path d="M18,6.589c0,0.192-0.141,0.374-0.279,0.513l-3.928,3.793l0.93,5.355c0.012,0.076,0.012,0.138,0.012,0.217
c0,0.278-0.131,0.532-0.443,0.532c-0.15,0-0.303-0.055-0.434-0.128L9,14.343l-4.856,2.53c-0.141,0.072-0.281,0.126-0.433,0.126
c-0.313,0-0.454-0.256-0.454-0.535c0-0.075,0.01-0.137,0.021-0.214l0.93-5.355L0.27,7.103C0.141,6.964,0,6.783,0,6.589
c0-0.322,0.335-0.451,0.605-0.492l5.43-0.782l2.434-4.874C8.567,0.236,8.751,0,9,0s0.433,0.236,0.529,0.439l2.435,4.874l5.431,0.782
C17.652,6.138,18,6.266,18,6.589L18,6.589" />
</g>
<linearGradient id="9Gradient">
<stop offset="90%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="8Gradient">
<stop offset="80%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="7Gradient">
<stop offset="70%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="6Gradient">
<stop offset="60%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="5Gradient">
<stop offset="50%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="4Gradient">
<stop offset="40%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="3Gradient">
<stop offset="30%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="2Gradient">
<stop offset="20%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
<linearGradient id="1Gradient">
<stop offset="10%" stop-color="#fdd119"></stop>
<stop stop-color="#eae7de"></stop>
</linearGradient>
</defs>
</svg>
<div class="ratingStars" data-rating-value="4.2">
<svg height="100%" width="500" class="star" viewBox="0 0 92 17">
<desc>
<p>Rating of 4.2 out of 5 stars</p>
</desc>
<use href="#iconStarRating" xlink:href="#iconStarRating" x="0" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="18.5" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="37" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="55.5" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="74" y="0" />
</svg>
</div>
<div class="ratingStars" data-rating-value="2.6">
<svg height="100%" width="500" class="star" viewBox="0 0 92 17">
<desc>
<p>Rating of 2.6 out of 5 stars</p>
</desc>
<use href="#iconStarRating" xlink:href="#iconStarRating" x="0" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="18.5" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="37" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="55.5" y="0" />
<use href="#iconStarRating" xlink:href="#iconStarRating" x="74" y="0" />
</svg>
</div>
<!-- JQUERY VERSION -->
<script>
var ratingStars = jQuery('.ratingStars');
ratingStars.each(function() {
// get the data attribute value and split it
var substr = jQuery(this).attr('data-rating-value').split('.');
// integer
var substrInt = substr[0];
//decimal
var substrDec = substr[1];
jQuery(this).find('use').each(function(i) {
if (i < substrInt) {
// Paint integer part
jQuery(this).addClass('star-full');
} else if (i == substrInt) {
// Paint decimal part
jQuery(this).addClass('star-' + substrDec);
} else if (i > substrInt) {
jQuery(this).addClass('star-empty');
}
});
});
</script>
<!-- PURE VANILLA VERSION BASED ON ID -->
<!-- script>
function iconStarRating(id) {
// get the current element based on the attribute
var ratingStars = document.getElementById(id);
// get the data attribute value and split it
var substr = ratingStars.getAttribute("data-rating-value").split('.');
// integer
var substrInt = substr[0];
//decimal
if (id.indexOf("evCity") == 0) {
if (substr[1] !== undefined) {
var substrDec = 'starA-' + substr[1];
} else {
var substrDec = 'starA-empty';
}
} else {
if (substr[1] !== undefined) {
var substrDec = 'star-' + substr[1];
} else {
var substrDec = 'star-empty';
}
}
// get array of 'use' elements from inside the identified by ID div
var useElementsArr = ratingStars.querySelectorAll("use");
// looping through 'use' elements
for (var i=0; i < 5; i++) {
var el = useElementsArr[i];
// whenever element number in loop is lower than integer number in rating part ...
if (i < substrInt) {
// Paint integer part
el.setAttribute('class', 'star-full');
// once the element number in loop is equal to the integer ...
} else if (i == substrInt) {
// Paint decimal part
el.setAttribute('class', substrDec);
} else if (i > substrInt) {
if (id.indexOf("evCity") == 0) {
el.setAttribute('class', 'starA-empty');
} else {
el.setAttribute('class', 'star-empty');
}
}
}
}
</script -->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment