In this article, I will show you how to make the visual part of the star rating. Namely:
- how to style
- how to make a hover
- how to save star fill after click
Finished option:
Markup
As a markup, we have a container block with the .rate class inside which I have placed 5 links. I used a font as a star. But most likely in practice you will have to use an image instead.
<div class="rate">
<a href="#">☆</a>
<a href="#">☆</a>
<a href="#">☆</a>
<a href="#">☆</a>
<a href="#">☆</a>
</div>
Styles
When styling, pay attention to the following:
- so that each link has position: relative;
.rate a{
text-decoration: none;
color: yellow;
position: relative;
display: inline-block;
}
- Create a :before pseudo-element. We will use it as a star placeholder. In the default state, assign it opacity: 0;
.rate a:before{
content: '★';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-event: none;
opacity: 0;
}
- when hovering, we will assign the .hover class to the link, and when clicking on it, we will assign the .active class. These classes will make our pseudo-element visible. Therefore, we also prescribe this moment in styles.
.rate a.hover:before,
.rate a.active:before{
opacity: 1;
}
Script
In the script, we collect our stars on the page and for each of them we prescribe the addition or removal of the corresponding class on hover or on click
let rateLink = document.querySelectorAll('.rate a');
rateLink.forEach((link, i) => {
//mouseenter
link.addEventListener('mouseenter', function(e){
let num = 0;
while(num <= i){
rateLink[num].classList.add('hover');
num++;
}
});
//mouseleave
link.addEventListener('mouseleave', function(e){
rateLink.forEach(item => {
item.classList.remove('hover');
});
});
//click
link.addEventListener('click', function(e){
e.preventDefault();
let num = 0;
rateLink.forEach(item => {
item.classList.remove('active');
});
while(num <= i){
rateLink[num].classList.add('active');
num++;
}
});
});