Half-Star Rating
An SVG star rating that supports half values on hover and click, with a live readout.
<div class="rate">
<div class="rate-stars" id="stars"></div>
<div class="rate-out" id="out">Rate this</div>
</div>*{box-sizing:border-box}
.rate{text-align:center;font-family:system-ui,sans-serif}
.rate-stars{display:inline-flex;gap:4px}
.rate-star{position:relative;width:40px;height:40px;cursor:pointer}
.rate-star svg{position:absolute;inset:0;width:100%;height:100%}
.rate-star .bg path{fill:#d6dae6}
.rate-star .fg{overflow:hidden;width:0}
.rate-star .fg path{fill:#ffb703}
.rate-out{margin-top:14px;font-weight:700;color:#1a1f36;font-size:15px}var wrap=document.getElementById('stars'),out=document.getElementById('out'),N=5,value=0;
var STAR='<path d="M20 2.5l5.4 11 12.1 1.8-8.8 8.5 2.1 12L20 38.1 8.2 35.8l2.1-12L1.5 15.3l12.1-1.8z" transform="scale(0.5)"/>';
for(var k=0;k<N;k++){var s=document.createElement('span');s.className='rate-star';s.dataset.i=k;
s.innerHTML='<svg class="bg" viewBox="0 0 40 40">'+STAR+'</svg><svg class="fg" viewBox="0 0 40 40">'+STAR+'</svg>';
wrap.appendChild(s)}
var stars=wrap.querySelectorAll('.rate-star');
function paint(v){stars.forEach(function(s,i){var p=Math.max(0,Math.min(1,v-i))*100;s.querySelector('.fg').style.width=p+'%'})}
function valFrom(e,s){var r=s.getBoundingClientRect();return +s.dataset.i+((e.clientX-r.left)/r.width>.5?1:0.5)}
stars.forEach(function(s){
s.addEventListener('mousemove',function(e){paint(valFrom(e,s))});
s.addEventListener('click',function(e){value=valFrom(e,s);out.textContent=value+' / 5'});
});
wrap.addEventListener('mouseleave',function(){paint(value)});Free to use.This snippet is plain HTML, CSS and JavaScript with no dependencies. Copy any file, or download the whole thing as a single ready-to-open .html page.