Fill Only Half a Star with Svg

Is it possible to only show half of a SVG icon?

I have written a code to get you the idea; If you click on the right side of the star, its color changes to blue and if you click on the left side, its color changes to gold. Also, it's better to not use stopPropagation and check e.target of the event.

const starIcon = document.getElementById("star");
const icon = document.getElementById("icon");
starIcon.onclick = e => {
starIcon.style.color = "blue";
e.stopPropagation();
};
icon.onclick = e => {
starIcon.style.color = "gold";
}
i {
clip-path: inset(0 0 0 50%);
color: gold;
}
  <!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" rel="stylesheet">
</head>

<body>
<span id="icon"><i id="star", class="fas fa-star"></i></span>
</body>

</html>

html css fill a svg but only 50% height

You can us a clipPath to do so

.ikoncircle {
position: absolute;
box-sizing: border-box;
display: inline-block;
width: 3rem;
height: 3rem;
border-radius: 50%;
background-color: rgba(20, 19, 23, 0.8);
}

#can {
right: 0.1%;
bottom: 24%;
}

.genelsvgs {
position: absolute;
right: 50%;
bottom: 50%;
transform: translate(50%, 50%);
width: 26px;
}

.cls-1 {
fill: red;
}

.bg {
fill: #fff;
}
<span class="ikoncircle" id="can">
<svg class="genelsvgs" id="katman_1" data-name="katman 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
<defs>
<clipPath id="cut-off-bottom">
<rect x="0" y="20" width="200" height="20" />
</clipPath>
</defs>
<title>kalp</title>

<path class="bg" d="M1.11,13.75c.13-4,1.58-7.26,5.5-8.88,4.08-1.68,7.85-.84,11.3,1.77a4.22,4.22,0,0,1,.91.88c.75,1,1.37.93,2.26,0A11.36,11.36,0,0,1,29.25,4c6.45-.16,10.52,5.52,9.48,11.56-.78,4.55-3.46,8.06-6.3,11.5-3.26,4-7.35,7-11.17,10.36A1.63,1.63,0,0,1,19,37.6C12.87,32.83,7.05,27.76,3.1,20.94A13.31,13.31,0,0,1,1.11,13.75Z"/>
<path class="cls-1" d="M1.11,13.75c.13-4,1.58-7.26,5.5-8.88,4.08-1.68,7.85-.84,11.3,1.77a4.22,4.22,0,0,1,.91.88c.75,1,1.37.93,2.26,0A11.36,11.36,0,0,1,29.25,4c6.45-.16,10.52,5.52,9.48,11.56-.78,4.55-3.46,8.06-6.3,11.5-3.26,4-7.35,7-11.17,10.36A1.63,1.63,0,0,1,19,37.6C12.87,32.83,7.05,27.76,3.1,20.94A13.31,13.31,0,0,1,1.11,13.75Z" clip-path="url(#cut-off-bottom)"/>
</svg>
</span>

How to fill only a part of the SVG?

The simplest way to do this is with a <linearGradient>.

function setWaterLevel(percent){  document.getElementById("stop1").setAttribute("offset", percent+"%");  document.getElementById("stop2").setAttribute("offset", percent+"%");}

document.getElementById("slider").addEventListener("input", function(evt) { setWaterLevel(evt.target.value);});
setWaterLevel(0);
<svg width="300px" viewBox="0 0 100 100">  <defs>    <linearGradient id="water" x1="0" y1="1" x2="0" y2="0">      <stop id="stop1" offset="0%" stop-color="blue"/>      <stop id="stop2" offset="0%" stop-color="transparent"/>    </linearGradient>  </defs>
<polygon points="0,0, 100,0, 80,100, 20,100" fill="url(#water)" stroke="black"/></svg>
<br><input id="slider" type="range" min="0" max="100" step="10" value="0"/>

fill half of svg polygon shape - star

You can define a gradient using another svg (to avoid repeating it inside each one) and use the gradient with fill. You can easily adjust the % values or create more gradient if you want different other fill

.rating-block {  padding: 2px 5px;  display: flex;  align-items: center;  justify-content: space-between;}
.rating-block .ratings-type { margin-right: 1rem; margin-bottom: 0;}
.rating-block .rating-block { display: flex; align-items: center; margin-bottom: 2rem;}
.rating-block .rating-block-rating { display: flex;}
.rating-block .star { cursor: pointer; stroke: #cc4b37;}
.rating-block .rating-block-rating .star.selected polygon { fill: #cc4b37;}.rating-block .rating-block-rating .star.half polygon { fill: url(#grad);}
.rating-block .rating-block-rating.is-voted .star polygon { fill: #cc4b37;}
.rating-block .rating-block-rating.is-voted .star.selected~.star polygon { fill: transparent;}
<svg height="0" width="0">  <defs>    <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">      <stop offset="0%" style="stop-color:#cc4b37;stop-opacity:1" />      <stop offset="50%" style="stop-color:#cc4b37;stop-opacity:1" />      <stop offset="50%" style="stop-color:transparent;stop-opacity:1" />      <stop offset="100%" style="stop-color:transparent;stop-opacity:1" />    </linearGradient>  </defs></svg>
<div class="rating-block"> <div class="rating-block-rating" data-rating> <div class="star selected"> <svg xmlns="http://www.w3.org/2000/svg" width="40" height="37" viewBox="0 0 40 37"> <polygon fill="none" points="272 30 260.244 36.18 262.489 23.09 252.979 13.82 266.122 11.91 272 0 277.878 11.91 291.021 13.82 281.511 23.09 283.756 36.18" transform="translate(-252)" /> </svg> </div> <div class="star half"> <svg xmlns="http://www.w3.org/2000/svg" width="40" height="37" viewBox="0 0 40 37"> <polygon fill="none" points="272 30 260.244 36.18 262.489 23.09 252.979 13.82 266.122 11.91 272 0 277.878 11.91 291.021 13.82 281.511 23.09 283.756 36.18" transform="translate(-252)" /> </svg> </div> <div class="star"> <svg xmlns="http://www.w3.org/2000/svg" width="40" height="37" viewBox="0 0 40 37"> <polygon fill="none" points="272 30 260.244 36.18 262.489 23.09 252.979 13.82 266.122 11.91 272 0 277.878 11.91 291.021 13.82 281.511 23.09 283.756 36.18" transform="translate(-252)" /> </svg> </div> <div class="star"> <svg xmlns="http://www.w3.org/2000/svg" width="40" height="37" viewBox="0 0 40 37"> <polygon fill="none" points="272 30 260.244 36.18 262.489 23.09 252.979 13.82 266.122 11.91 272 0 277.878 11.91 291.021 13.82 281.511 23.09 283.756 36.18" transform="translate(-252)" /> </svg> </div> <div class="star"> <svg xmlns="http://www.w3.org/2000/svg" width="40" height="37" viewBox="0 0 40 37"> <polygon fill="none" points="272 30 260.244 36.18 262.489 23.09 252.979 13.82 266.122 11.91 272 0 277.878 11.91 291.021 13.82 281.511 23.09 283.756 36.18" transform="translate(-252)" /> </svg> </div> </div></div>

How to fill an svg image with specific length color

Here are two quick hack solutions, both of which require modification of the SVG (and both of which could be modified in a more efficient way), and both of which use a gradient fill, the same basic idea that Robert Longson suggested above.

1. duplicate the path, fill with gradient

  1. Duplicate the path so you have one copy for the border and one copy for the fill.
  2. Remove the fill-rule="evenodd" from the first path so the interior isn't subtracted, thus getting filled too.
  3. Fill the first path (the "back" one) with a gradient that uses hard stops to achieve your partial fill. (I've used orange here just so you can see which is which.)

You could fiddle with the specifics of the gradient to get it exactly where you want it of course. This is just a proof of concept.

svg {
max-width: 200px; /* not relevant */
}

.stop1 {
stop-color: orange;
}

.stop2 {
stop-opacity: 0;
}

path.fill {
fill: url(#gradient-fill);
}
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
<defs>
<linearGradient id="gradient-fill" x1="0" x2="1" y1="1" y2="0.5">
<stop class="stop1" offset="70%"/>
<stop class="stop2" offset="70%"/>
</linearGradient>
</defs>
<path class="fill" d="M9.177 7.72a.5.5 0 0 1-.376.273l-5.309.771a.5.5 0 0 0-.277.853l3.841 3.745a.5.5 0 0 1 .144.442l-.907 5.288a.5.5 0 0 0 .726.527l4.748-2.497a.5.5 0 0 1 .466 0l4.748 2.497a.5.5 0 0 0 .726-.527l-.907-5.288a.5.5 0 0 1 .143-.442l3.842-3.745a.5.5 0 0 0-.277-.853l-5.309-.771a.5.5 0 0 1-.376-.274l-2.375-4.81a.5.5 0 0 0-.896 0l-2.375 4.81zM12 6.52l-1.03 2.084a2.5 2.5 0 0 1-1.88 1.368l-2.302.334 1.665 1.624a2.5 2.5 0 0 1 .72 2.212l-.394 2.292 2.059-1.082a2.5 2.5 0 0 1 2.326 0l2.059 1.082-.393-2.292a2.5 2.5 0 0 1 .718-2.212l1.666-1.624-2.302-.334a2.5 2.5 0 0 1-1.882-1.368L12 6.52z"/>

<path fill-rule="evenodd" d="M9.177 7.72a.5.5 0 0 1-.376.273l-5.309.771a.5.5 0 0 0-.277.853l3.841 3.745a.5.5 0 0 1 .144.442l-.907 5.288a.5.5 0 0 0 .726.527l4.748-2.497a.5.5 0 0 1 .466 0l4.748 2.497a.5.5 0 0 0 .726-.527l-.907-5.288a.5.5 0 0 1 .143-.442l3.842-3.745a.5.5 0 0 0-.277-.853l-5.309-.771a.5.5 0 0 1-.376-.274l-2.375-4.81a.5.5 0 0 0-.896 0l-2.375 4.81zM12 6.52l-1.03 2.084a2.5 2.5 0 0 1-1.88 1.368l-2.302.334 1.665 1.624a2.5 2.5 0 0 1 .72 2.212l-.394 2.292 2.059-1.082a2.5 2.5 0 0 1 2.326 0l2.059 1.082-.393-2.292a2.5 2.5 0 0 1 .718-2.212l1.666-1.624-2.302-.334a2.5 2.5 0 0 1-1.882-1.368L12 6.52z"/>

</svg>

Fill half of SVG circle

You can do something like that: