htmlcsssvglinear-gradientsstroke

Move stroke gradient definition from SVG to CSS


There is a gradient, defined like this:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="out-of-flow">
    <defs>
        <!-- Gradients for circle charts. -->
        <linearGradient id="circle-graph-blue-greenish-gradient">
            <stop offset="0" stop-color="#00d5bd" />
            <stop offset="100" stop-color="#24c1ed" />
        </linearGradient>
    </defs>
</svg>

It is referenced in a CSS class, applied to a <path> in another <svg>:

.circle-graph-blue-greenish {
  stroke: url(#circle-graph-blue-greenish-gradient);
  stroke-width: 5;
  fill: transparent;
  stroke-linecap: round;
  stroke-linejoin: round;
}

svg {
  height: 50vh;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="out-of-flow">
    <defs>
        <!-- Gradients for circle charts. -->
        <linearGradient id="circle-graph-blue-greenish-gradient">
            <stop offset="0" stop-color="#00d5bd" />
            <stop offset="100" stop-color="#24c1ed" />
        </linearGradient>
    </defs>
</svg>

<svg class="rotate-90" width="75%" viewBox="0 0 100 100">
    <path class="circle-graph-underlay" d="M5,50 A45,45,0 1 1 95,50 A45,45,0 1 1 5,50"></path>
    <path d="M5,50 A45,45,0 1 1 95,50 A45,45,0 1 1 5,50" class="circle-graph circle-graph-blue-greenish"
        style="stroke-dashoffset: 251.677;stroke-dasharray: 282.783;"></path>
</svg>

It perfectly works. I want to move the gradient definition into the CSS class:

.circle-graph-blue-greenish
{
    stroke: linear-gradient(0deg, rgba(0,213,189,1) 0%, rgba(36,193,237,1) 100%);
    stroke-width: 5;
    fill: transparent;
    stroke-linecap: round;
    stroke-linejoin: round;
}

But unfortunately it has stopped working (no visible stroke).

Why aren't both definitions equivalent and how do I define the gradient for stroke in CSS?

UPD It seems I can move the color values:

<stop offset="0" stop-color="var(--circle-graph-blue-greenish-gradient-color-1)" />

Better than nothing.

UPD 2 Unfortunately, the answer from here is not satisfactory for me.

It seems it is impossible to use variables like this:

.circle-graph-blue-greenish
{
    /*stroke: url(#circle-graph-blue-greenish-gradient);*/
    --color1: blue;
    --color2: red;
    stroke: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cdefs%3E%3ClinearGradient id='gradient'%3E%3Cstop offset='0' stop-color='var(--color1)' /%3E%3Cstop offset='1' stop-color='var(--color2)' /%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E#gradient");
    stroke-width: 5;
    fill: transparent;
    stroke-linecap: round;
    stroke-linejoin: round;
}

Using a duplicate value violates DRY and (especially, inside a quoted string) could be easy to overlook.


Solution

  • Tempting to do the whole thing in CSS. You don’t get the rounded line caps, but the code is so much neater.

    .pie {
      --my-grey: #333333f4;
      --my-cyan: #00d5bd;
      --my-blue: #0072d5;
      width: 200px;
      aspect-ratio: 1;
      border-radius: 50%;
    
      background-image:
        /* top layer masks the centre - can change this to solid black */
        radial-gradient(circle, var(--my-grey) 60%, transparent 60%),
        /* centre layer is the colourful edge */
        conic-gradient(transparent 75%, var(--my-blue) 75%, var(--my-cyan) 90%, transparent 90%),
        /* bottom layer is the black foundation */
        radial-gradient(circle, black 65%, transparent 65%);
    }
    <div class="pie"></div>