Donut chart using gradients colors and rounded caps

Viewed 26

I managed to get to this but I still can't figure out how to make the gradient stay when I have for example 20%. Show mostly green and a little bit of yellow.

This is what I have to do: enter image description here

Here the best of my attempts

.pie {
  --p:75;      /* the percentage */
  --b:22px;    /* the thickness */
  --w:150px;   /* the size*/
  
  width:var(--w);
  aspect-ratio:1/1;
  position:relative;
  display:inline-grid;
  margin:5px;
  place-content:center;
  font-size:25px;
  font-weight:bold;
  font-family:sans-serif;
}
.pie:before,
.pie:after {
  content:"";
  position:absolute;
  border-radius:50%;
}
.pie:before {
  inset:0;
  background:
    radial-gradient(farthest-side,#007953 98%,#0000) top/var(--b) var(--b) no-repeat,
    conic-gradient(from 0deg, #007953 1%, #FCE945 calc(var(--p)*0.5%), #EB001B calc(var(--p)*1%),#EBF0F5 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
          mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}
.pie:after {
  inset:calc(50% - var(--b)/2);
  background:#EB001B;
  transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
<div class="pie animate" >75%</div>

Here I leave you how it would look if I put 20%. In that case the gradient is seen as cut off, the rounded caps are seen and the color gradient is not respected. That is if it is respected but with 20% you should see almost all green and not all three colors.

.pie {
  --p:20;      /* the percentage */
  --b:22px;    /* the thickness */
  --w:150px;   /* the size*/
  
  width:var(--w);
  aspect-ratio:1/1;
  position:relative;
  display:inline-grid;
  margin:5px;
  place-content:center;
  font-size:25px;
  font-weight:bold;
  font-family:sans-serif;
}
.pie:before,
.pie:after {
  content:"";
  position:absolute;
  border-radius:50%;
}
.pie:before {
  inset:0;
  background:
    radial-gradient(farthest-side,#007953 98%,#0000) top/var(--b) var(--b) no-repeat,
    conic-gradient(from 0deg, #007953 1%, #FCE945 calc(var(--p)*0.5%), #EB001B calc(var(--p)*1%),#EBF0F5 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
          mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}
.pie:after {
  inset:calc(50% - var(--b)/2);
  background:#EB001B;
  transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
<div class="pie animate" >20%</div>

1 Answers

Here is an update to the code you are using where I will consider mix-blend-mode to approximate the result you want. Still not perfect on the edges but will try to improve later:

.pie {
  --p:20;      /* the percentage */
  --b:22px;    /* the thickness */
  --w:150px;   /* the size*/
  
  width:var(--w);
  aspect-ratio:1/1;
  position:relative;
  display:inline-grid;
  margin:5px;
  place-content:center;
  font-size:25px;
  font-weight:bold;
  font-family:sans-serif;
  background:
    radial-gradient(farthest-side,#fff calc(99% - var(--b)),#0000 calc(100% - var(--b))),
    conic-gradient(from -10deg,#007953, #FCE945, #EB001B);
  border-radius: 50%;
  overflow:hidden;
}
.pie:before,
.pie:after {
  content:"";
  position:absolute;
  mix-blend-mode: lighten;
}
.pie:before {
  inset:0;
  background:
    radial-gradient(farthest-side,#000 98%,#0000) top/var(--b) var(--b) no-repeat,
    conic-gradient(from 0deg, #000 calc(var(--p)*1% - 1%),#0000 0 calc(var(--p)*1% + 2.5%),#EBF0F5 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
          mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}
.pie:after {
  inset: calc(50% - var(--b)/2);
  background:
    radial-gradient(#000 66%,#0000 67%),
    linear-gradient(#0000 50%,#EBF0F5 0);
  transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
<div class="pie" >20%</div>

<div class="pie" style="--p:40">40%</div>


<div class="pie" style="--p:70">70%</div>

<div class="pie" style="--p:90">90%</div>

Related