4

I'm trying to add a gradient to the stroke of a line which fades out at the top but having no luck. Actually I kind of got it working like this, but it has browser issues even in Chrome certain SVG sizes where the gradient just breaks and is solid:

<linearGradient
  id='whiteFadeGrad'
  x1={svgHeight}
  y1='0'
  x2='0'
  y2={svgHeight}
  gradient-units='userSpaceOnUse'
>
  <stop offset='0' stop-color='rgba(255,255,255,0)' />
  <stop offset='1' stop-color='rgba(255,255,255,0.2)' />
</linearGradient>

I would much rather stick to using percentage units, but can't get it to work:

<p>The solid green one works, but you can't see the other when I apply the gradient to it. I've tried a lot of different x1/x2/y1/y2 values as well as gradientTransform(rotate(d)).</p>

<svg height="200" width="500">
  <defs>
    <linearGradient id='fadeGrad' x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset='0%' stop-color='red' />
      <stop offset='100%' stop-color='blue' />
    </linearGradient>
  </defs>
  <line x1="100" y1="0" x2="100" y2="200" style="stroke: green; stroke-width:4px; shape-rendering: crispEdges;" />
  <line x1="120" y1="0" x2="120" y2="200" style="stroke: url('#fadeGrad'); stroke-width:4px; shape-rendering: crispEdges;" />
</svg>

Thanks

Dominic
  • 62,658
  • 20
  • 139
  • 163

2 Answers2

7

It looks like a bug and a hack, but worked:

<svg height="200" width="500">
  <defs>
    <linearGradient id='fadeGrad' x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset='0%' stop-color='red' />
      <stop offset='100%' stop-color='blue' />
    </linearGradient>
  </defs>
  <line x1="100" y1="0" x2="100" y2="200" style="stroke: green; stroke-width:4px; shape-rendering: crispEdges;" />
  <line x1="120" y1="0" x2="120.001" y2="200" style="stroke: url('#fadeGrad'); stroke-width:4px; shape-rendering: crispEdges;" />
</svg>

You might probably use <rect> instead of <line>, which is not so hacky:

<svg height="200" width="500">
  <defs>
    <linearGradient id='fadeGrad' x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset='0%' stop-color='red' />
      <stop offset='100%' stop-color='blue' />
    </linearGradient>
  </defs>
  <line x1="100" y1="0" x2="100" y2="200" style="stroke: green; stroke-width:4px; shape-rendering: crispEdges;" />
  <rect x="120" y="0" width="4" height="200" style="fill: url('#fadeGrad'); shape-rendering: crispEdges;" />
</svg>
Kosh
  • 16,966
  • 2
  • 19
  • 34
  • hah that's crazy! How did you figure it out? Seems like FF has the same issue so must be some bizarre spec thing. thanks – Dominic Jan 31 '20 at 04:29
  • @Dominic, yep, it's crazy as only vertical and horizontal lines are not displayed properly. I've updated the answer with another option, if it works for you. – Kosh Jan 31 '20 at 04:39
1

Check this, I dont know much about SVG, but a simple googling does the job for me.

Could you please go through the code.

<p>The solid green one works, but you can't see the other when I apply the gradient to it. I've tried a lot of different x1/x2/y1/y2 values as well as gradientTransform(rotate(d)).</p>

<svg height="200" width="500">
  <defs>
    <linearGradient id="e" x1="40" y1="210" x2="400" y2="210" gradientUnits="userSpaceOnUse" gradientTransform="rotate(90)">
        <stop stop-color="steelblue" offset="0" />
        <stop stop-color="red" offset="1" />
    </linearGradient>
  </defs>
  <line x1="100" y1="0" x2="100" y2="200" style="stroke: green; stroke-width:10px; shape-rendering: crispEdges;" />
  <line x1="120" y1="0" x2="120" y2="200" style="stroke: url('#e'); stroke-width:4px; shape-rendering: crispEdges;" />
</svg>
Akhil Aravind
  • 5,741
  • 16
  • 35
  • Thanks as mentioned I wanted to try and avoid using userSpaceOnUse as I have an issue with it, though yet to see if that issue is fixed using %, anyway upvote for the effort – Dominic Jan 31 '20 at 04:29