<h1>Pure CSS Star Rating System!!</h1>
<p>Using a sort of <strong>"previous sibling"</strong> selector</p>
<div class="rating">
<!--elements are in reversed order, to allow "previous sibling selectors" in CSS-->
<input aria-flowto="rating0" class="rating__input" type="radio" name="rating" value="5" id="rating5">
<label class="rating__label" for="rating5">☆
<span class="rating__star">5 Stars</span>
</label>
<input aria-flowto="rating5" class="rating__input" type="radio" name="rating" value="4" id="rating4">
<label class="rating__label" for="rating4">☆
<span class="rating__star">4 Stars</span>
</label>
<input aria-flowto="rating4" class="rating__input" type="radio" name="rating" value="3" id="rating3">
<label class="rating__label" for="rating3">☆
<span class="rating__star">3 Stars</span>
</label>
<input aria-flowto="rating3" class="rating__input" type="radio" name="rating" value="2" id="rating2">
<label class="rating__label" for="rating2">☆
<span class="rating__star">2 Stars</span>
</label>
<input aria-flowto="rating2" class="rating__input" type="radio" name="rating" value="1" id="rating1" aria-flowto="rating2">
<label class="rating__label" for="rating1">☆
<span class="rating__star">1 Stars</span>
</label>
<input aria-flowto="rating1" class="rating__input" type="radio" name="rating" value="0" id="rating0">
<label class="rating__label rating__label--hidden" for="rating0">
<span class="rating__star">Not rated yet </span>
</label>
</div>
/*shows the stars side by side, centered, and in reverse order than the HMTL*/
.rating {
display: flex;
flex-direction: row-reverse;
justify-content: center;
border: 3px dashed #333;
padding: 1em;
}
/*hides the radio buttons by forcing them out of the viewport*/
.rating__input{
position: absolute;
left: -100vw;
}
/*hides label for 0 (unset)star rating */
.rating__label--hidden{
display:none;
}
/* hides spans from sighted users */
.rating__star{
position: absolute; left: -100vw;
font-size: 1px
}
.rating:hover,
.rating:focus-within,
.rating:active {
border-color: yellow;
}
/*style the empty stars, sets position:relative as base for pseudo-elements*/
.rating__label {
position: relative;
width: 1.1em;
font-size: 15vw;
color: #FFD700;
cursor: pointer;
}
/* sets filled star pseudo-elements */
.rating__label::before{
content: "\2605";
position: absolute;
opacity: 0;
}
/*overlays a filled start character to the hovered element and all previous siblings*/
.rating__label:hover:before,
.rating__label:hover ~ .rating__label:before {
opacity: 1 !important;
}
/*overlays a filled start character on the selected element and all previous siblings*/
.rating__input:checked ~ .rating__label:before{
opacity:1;
}
/*when an element is selected and pointer re-enters the rating container, selected rate and siblings get semi transparent, as reminder of current selection*/
.rating:hover > .rating__input:checked ~ .rating__label:before{ opacity: 0.4; }
/*just aesthetics*/
body{ background: #222225; color: white;}
h1, p{ text-align: center;}
p{ font-size: 1.2rem;}
@media only screen and (max-width: 600px) {
h1{font-size: 14px;}
p{font-size: 12px;}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.