linearGradient not working for SVG sprites - html

I am trying to combine all svg icons into one sprite file like this for organization, caching and other purposes. But for some reason, linearGradient is not being applied
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<!-- other icons -->
<!-- ... -->
<g id="toggle">
<path d="M4,7.992c-2.206,0-4-1.794-4-4c0-2.206,1.794-4,4-4h10c2.206,0,4,1.794,4,4c0,2.206-1.794,4-4,4H4z"/>
<circle fill="url('#toggle-linear-gradient')" cx="14" cy="3.992" r="3"/>
<defs>
<linearGradient id="toggle-linear-gradient" gradientUnits="userSpaceOnUse" x1="14" y1="0.9922" x2="14" y2="6.9922">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="1" stop-color="#8C8C8B"/>
</linearGradient>
</defs>
</g>
</svg>
Now, in file preview I can see circle with applied gradient correctly
When I try to import it into my HTML like this
<svg>
<use href="#toggle" xlink:href="#toggle"></use>
</svg>
the circle is not being colored with defined gradient
When I moved <linearGradient> out of svg file, it worked, but why?
<svg>
<linearGradient id="toggle-linear-gradient" gradientUnits="userSpaceOnUse" x1="14" y1="0.9922" x2="14" y2="6.9922">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="1" stop-color="#8C8C8B"/>
</linearGradient>
<use href="#toggle" xlink:href="#toggle"></use>
</svg>
Even tho it worked, the problem is, that this kills the purpose of keeping all the icons in one file if some styling can only be defined from the outside. Displaying same icon will force me defining same gradient multiple times. Would love to have everything in the same file. Any ideas or insights?
P.S. importing as <img> displays the circle gradient correctly.

Pretty sure, you have hidden your main svg asset file by display:none.
If you change this to visibility:hidden it should work:
function unhide(){
document.querySelector('.dsp-non').classList.remove('dsp-non');
}
.svgAssetHidden{
visibility:hidden;
position:absolute;
width:0px;
height:0px;
overflow:hidden;
}
.svgIcon{
display:inline-block;
width:10em;
}
.dsp-non{
display:none;
}
<button onclick="unhide()">remove display:none</button>
<h3>visibility:hidden</h3>
<svg class="svgIcon" viewBox="0 0 50 20">
<use href="#toggle" href="#toggle"></use>
</svg>
<h3>display:none</h3>
<svg class="svgIcon" viewBox="0 0 50 20">
<use href="#toggle2" href="#toggle"></use>
</svg>
<svg class="svgAssetHidden" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<!-- other icons -->
<!-- ... -->
<g id="toggle">
<path d="M4,7.992c-2.206,0-4-1.794-4-4c0-2.206,1.794-4,4-4h10c2.206,0,4,1.794,4,4c0,2.206-1.794,4-4,4H4z"/>
<circle fill="url('#toggle-linear-gradient')" cx="14" cy="3.992" r="3"/>
<defs>
<linearGradient id="toggle-linear-gradient" gradientUnits="userSpaceOnUse" x1="14" y1="0.9922" x2="14" y2="6.9922">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="1" stop-color="#8C8C8B"/>
</linearGradient>
</defs>
</g>
</svg>
<svg class="svgAssetDspNon dsp-non" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<!-- other icons -->
<!-- ... -->
<g id="toggle2">
<path d="M4,7.992c-2.206,0-4-1.794-4-4c0-2.206,1.794-4,4-4h10c2.206,0,4,1.794,4,4c0,2.206-1.794,4-4,4H4z"/>
<circle fill="url('#toggle-linear-gradient2')" cx="14" cy="3.992" r="3"/>
<defs>
<linearGradient id="toggle-linear-gradient2" gradientUnits="userSpaceOnUse" x1="14" y1="0.9922" x2="14" y2="6.9922">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="1" stop-color="#8C0000"/>
</linearGradient>
</defs>
</g>
</svg>
Hiding a svg by display:none will also break some other features like filters.

Related

How can I use gradients from SVG symbols in other files?

I have found that when I have a source SVG with a symbol and a destination SVG that access the source SVG with <use>, the symbol is imported and is able to access the gradient (perhaps because it is simply already on the page). However, when the source SVG is in a different file, the objects in the <symbol> are imported but not the gradient. How can I import the gradient as well?
Here is some MCVE code:
index.html:
<style>
html,body,svg { width: 100% }
</style>
<!-- inline SVG with gradient -->
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="myDot" width="10" height="10" viewBox="0 0 2 2">
<linearGradient id="linear-gradient" x1="0.133" y1="0.008" x2="0.949" y2="1.101" gradientUnits="objectBoundingBox">
<stop offset="0.042" stop-color="#21dbaa"/>
<stop offset="0.358" stop-color="#00b4ef"/>
<stop offset="0.433" stop-color="#01a7ec"/>
<stop offset="0.568" stop-color="#0487e4"/>
<stop offset="0.68" stop-color="#0768dd"/>
<stop offset="0.965" stop-color="#5f1ae5"/>
</linearGradient>
    <circle cx="1" cy="1" r="1" fill="url(#linear-gradient)"/>
  </symbol>
</svg>
<svg viewBox="0 0 200 60" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
 
  <!-- All instances of our symbol -->
  <use xlink:href="#myDot" x="5"  y="5" style="opacity:1.0" />
  <use xlink:href="#myDot" x="20" y="5" style="opacity:0.8" />
  <use xlink:href="symbol.svg#myDot" x="35" y="5" style="opacity:0.6" stroke="black" stroke-width=".1" />
  <use xlink:href="symbol.svg#myDot" x="50" y="5" style="opacity:0.4" stroke="black" stroke-width=".1" />
  <use xlink:href="symbol.svg#myDot" x="65" y="5" style="opacity:0.2" stroke="black" stroke-width=".1" />
</svg>
symbol.svg:
<!-- external SVG with gradient -->
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="myDot" width="10" height="10" viewBox="0 0 2 2">
<linearGradient id="linear-gradient" x1="0.133" y1="0.008" x2="0.949" y2="1.101" gradientUnits="objectBoundingBox">
<stop offset="0.042" stop-color="#21dbaa"/>
<stop offset="0.358" stop-color="#00b4ef"/>
<stop offset="0.433" stop-color="#01a7ec"/>
<stop offset="0.568" stop-color="#0487e4"/>
<stop offset="0.68" stop-color="#0768dd"/>
<stop offset="0.965" stop-color="#5f1ae5"/>
</linearGradient>
    <circle cx="1" cy="1" r="1" fill="url(#linear-gradient)"/>
  </symbol>
</svg>
Here is a working Codepen demo that illustrates the problem, using the same code as shown above. Notice how the two circles importing the symbol from the inline SVG in index.html are correctly displaying the gradient, but the three circles importing the symbol from symbol.svg are not displaying the gradient.
Edit: This may be a duplicate of another question asking about referencing gradients in external files.
Looks like browser support for this feature is still somewhat low (source). The example given in the question should in theory work in a couple years.
One workaround is to include the gradient definitions on every page where external SVGs are referenced and point to that instead.
index.html:
<svg style="height: 0; width: 0;" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="linear-gradient" x1="0.133" y1="0.008" x2="0.949" y2="1.101" gradientUnits="objectBoundingBox">
<stop offset="0.042" stop-color="#21dbaa"/>
<stop offset="0.358" stop-color="#00b4ef"/>
<stop offset="0.433" stop-color="#01a7ec"/>
<stop offset="0.568" stop-color="#0487e4"/>
<stop offset="0.68" stop-color="#0768dd"/>
<stop offset="0.965" stop-color="#5f1ae5"/>
</linearGradient>
</defs>
</svg>
<svg>
<use xlink:href="#myDot" fill="url(#linear-gradient)" />
</svg>
symbol.svg:
<svg viewBox="0 0 80 20" xmlns="http://www.w3.org/2000/svg">
<symbol id="myDot" width="10" height="10" viewBox="0 0 2 2">
<circle cx="1" cy="1" r="1" fill="url(#linear-gradient)"/>
</symbol>
</svg>

How to implement an animating gradient within my SVG example

Hi I've been looking at source code that implements a colour gradient on a quick example SVG that I made within Adobe Illustrator. For some reason I can't seem to work out how to get it to work such that the section "st0" are affected by the gradient named "logo-gradient".
Any help?
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
style="enable-background:new 0 0 47.4 47.7;" xml:space="preserve" width="50" height="50">
<defs>
<linearGradient id="logo-gradient" x1="50%" y1="0%" x2="50%" y2="100%" >
<stop offset="0%" stop-color="#7A5FFF">
<animate attributeName="stop-color" values="#7A5FFF; #01FF89; #7A5FFF" dur="4s" repeatCount="indefinite"></animate>
</stop>
<stop offset="100%" stop-color="#01FF89">
<animate attributeName="stop-color" values="#01FF89; #7A5FFF; #01FF89" dur="4s" repeatCount="indefinite"></animate>
</stop>
</linearGradient>
</defs>
<style type="text/css">
.st0{fill:"url('#logo-gradient')"}
</style>
<g id="Layer_2">
<rect x="-11.8" y="-9" width="66" height="63"/>
</g>
<g id="Layer_1">
<g>
<g>
<path d="M12.1,30.4v1c0,8.1,3.9,11.9,8.7,11.9c3.9,0,7.3-1.8,9.4-6.6h0.1c-1.4,7.4-5.8,11-12.5,11c-7,0-13.6-4.6-13.6-15.1
c0-11.4,7.1-15.6,13.9-15.6c6.1,0,12.2,3.2,12.2,11.8c0,0.5-0.1,1-0.1,1.5H12.1z M12.1,29.3h10.8c0.1-0.5,0.1-0.9,0.1-1.2
c0-6.9-1.6-10.1-5-10.1C14.4,18,12.4,21.9,12.1,29.3z"/>
<path d="M44.1,43.2c0,0.7,0.1,0.8,0.7,1.3l3.6,2.6v0.1h-16v-0.1l3.6-2.6c0.5-0.4,0.6-0.7,0.6-1.3V8.8c0-0.8-0.1-1-0.6-1.4
l-3.6-2.6V4.7l11.8-1.4V43.2z"/>
</g>
<g>
<path class="st0" d="M12.1,30.4v1c0,8.1,3.9,11.9,8.7,11.9c3.9,0,7.3-1.8,9.4-6.6h0.1c-1.4,7.4-5.8,11-12.5,11
c-7,0-13.6-4.6-13.6-15.1c0-11.4,7.1-15.6,13.9-15.6c6.1,0,12.2,3.2,12.2,11.8c0,0.5-0.1,1-0.1,1.5H12.1z M12.1,29.3h10.8
c0.1-0.5,0.1-0.9,0.1-1.2c0-6.9-1.6-10.1-5-10.1C14.4,18,12.4,21.9,12.1,29.3z"/>
<path class="st0" d="M44.1,43.2c0,0.7,0.1,0.8,0.7,1.3l3.6,2.6v0.1h-16v-0.1l3.6-2.6c0.5-0.4,0.6-0.7,0.6-1.3V8.8
c0-0.8-0.1-1-0.6-1.4l-3.6-2.6V4.7l11.8-1.4V43.2z"/>
</g>
</g>
</g>
</svg>

how to put an image in a svg with a higher z-index

I have a svg and I want to put an image inside of it.
The svg looks like a wave.
The image should be in front of the wave (visible) but the problem is it is now hiding behind the wave.
I tried already with a higher z-index but without result.
How can I make the image visible in front of the wave?
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="wave">
<svg viewBox="0 0 100 50" preserveAspectRatio="none" >
<g>
<!--<path d="M100,30 Q70,40 50,30 T0,30 v20 h100Z" -->
<path d="M100,30 Q70,60 50,30 T0,30 v20 h100Z"
style="stroke-linejoin:round; stroke:#f6f6f6" stroke-width="0"/>
</g>
</svg>
</symbol>
</svg>
<div class="svg-header-wave">
<svg class="header-wave" style="width: 100%; height: 150px" fill="url(#gradient)">
<image xlink:href="http://develop.webprofis.nl/wisselslag/img/logo.png" x="0" y="-30" width="300px" height="150px" style="z-index: 9999"/>
<defs>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#009de1"/>
<stop offset="100%" stop-color="#102b72"/>
</linearGradient>
</defs>
<use xlink:href="#wave"/>
</svg>
</div>
Here is a fiddle you can see what happens:
https://jsfiddle.net/jotect8j/7/
Just include the image tag after the wave.
SVG elements are by default layed over top of one another in the order of their inclusion.
So first element is at the bottom, while last is on top.
<svg class="header-wave" style="width: 100%; height: 150px" fill="url(#gradient)">
<defs>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#009de1"/>
<stop offset="100%" stop-color="#102b72"/>
</linearGradient>
</defs>
<use xlink:href="#wave"/>
<image xlink:href="http://develop.webprofis.nl/wisselslag/img/logo.png" x="0" y="-30" width="300px" height="150px" style="z-index: 9999"/>
</svg>
https://jsfiddle.net/gwat00Lr/1/
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="wave">
<svg viewBox="0 0 100 50" preserveAspectRatio="none" >
<g>
<!--<path d="M100,30 Q70,40 50,30 T0,30 v20 h100Z" -->
<path d="M100,30 Q70,60 50,30 T0,30 v20 h100Z"
style="stroke-linejoin:round; stroke:#f6f6f6" stroke-width="0"/>
</g>
<image xlink:href="http://develop.webprofis.nl/wisselslag/img/logo.png" x="0" y="-30" width="300px" height="150px" style="z-index: 9999"/>
</svg>
</symbol>
</svg>
<div class="svg-header-wave">
<svg class="header-wave" style="width: 100%; height: 150px" fill="url(#gradient)">
<defs>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#009de1"/>
<stop offset="100%" stop-color="#102b72"/>
</linearGradient>
</defs>
<use xlink:href="#wave"/>
</svg>
</div>
Here is a fiddle with working demo

SVG Symbol animate not working with Safari

I'm currently struggling with a SVG.
Right now, I'm trying to display an animated SVG in my webpage. In order to do it, I just put the svg code at the end of the body, and used the html tag "use" to embed my SVG (which contains a symbol).
Here is my SVG code :
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="100%" y1="0%" x2="0%" y2="100%" id="linearGradient">
<stop offset="0%" stop-color="#7A5FFF">
<animate attributeName="stop-color" values="#05FFA3; #45CAFC; #7873F5; #FC6262; #05FFA3;" dur="10s" repeatCount="indefinite"></animate>
</stop>
<stop offset="100%" stop-color="#01FF89">
<animate attributeName="stop-color" values="#2096FF; #303F9F; #FF6EC4; #FFD86F; #2096FF;" dur="10s" repeatCount="indefinite"></animate>
</stop>
</linearGradient>
</defs>
<symbol x="0px" y="0px" width="308px" height="308px" viewBox="0 0 308 308" id="svg-logo">
<circle cx="150" cy="150" r="150" fill="url(#linearGradient)" />
</symbol>
</svg>
And here is the way I embed it in my page :
<svg class="star">
<use xlink:href="#svg-logo">
</svg>
It works fine, except on safari. The linear gradient animation is completely broken, and looks like this :

SVG linear gradient set as background doesn't work in Edge and IE

I am using SVG shape with linear gradient color via
background: url(#{$imgUrlBase}/element.svg);
Works just fine everywhere, except for Edge and IE, where the shape appears correctly, but instead of gradient, there is only solid color.
For multiple reasons (simple use of png fallback) I would like to use this way of implementation. I did not find any not of limitation of this usage regarding Edge.
This is element.svg
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="l" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 308 308" style="enable-background:new 0 0 308 308;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#s);}
</style>
<g id="Page-1">
<defs>
<linearGradient id="s" gradientUnits="userSpaceOnUse" x1="-483.7941" y1="514.2445" x2="-484.1468" y2="514.5996" gradientTransform="matrix(620 0 0 -620 300215 319095)">
<stop offset="0" style="stop-color:#FF0000"/>
<stop offset="1" style="stop-color:#00FF00"/>
</linearGradient>
</defs>
<path id="shape" class="st0" d="..."/>
</g>
</svg>
Any idea how to make SVG with linear background work as a background image in Edge and IE 11?
There is something about that SVG that IE doesn't like. I think it may be the odd gradientTransform that's in there.
https://jsfiddle.net/efgtu2pj/
If you get rid of it and update the gradient coordinates to compensate, it renders fine.
<svg version="1.1" id="l" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 308 308">
<style type="text/css">
.st0{fill:url(#s);}
</style>
<g id="Page-1">
<defs>
<linearGradient id="s" gradientUnits="userSpaceOnUse" x1="308" y1="308" x2="-50" y2="0">
<stop offset="0" style="stop-color:#FF0000"/>
<stop offset="1" style="stop-color:#00FF00"/>
</linearGradient>
</defs>
<path id="shape" class="st0" d="M154,0,308,308,0,308"/>
</g>
</svg>
Note that the coords I have used aren't exactly equivalent. I have just chosen values that look to give approximately the same results as the original.
Here is an example of an SVG with a gradient that I exported out of illustrator, and then edited the SVG code to remove gradientTransform, and replaced x1, y1, x2, y2 values so that it works in internet explorer and edge:
Illustrator export:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="40px" height="150px" viewBox="0 0 40 150" enable-background="new 0 0 40 150" xml:space="preserve">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-1023.5181" y1="4587.5352" x2="-1023.2139" y2="4587.5352" gradientTransform="matrix(0 492.7101 -492.7101 0 2260344.5 504297.75)">
<stop offset="0" style="stop-color:#FFCC07"/>
<stop offset="0.5111" style="stop-color:#346966"/>
<stop offset="1" style="stop-color:#51538C"/>
</linearGradient>
<rect fill="url(#SVGID_1_)" width="40" height="150"/>
<path fill="#FFFFFF" d="M20.81,143.313c0.349-0.071,0.677-0.258,0.907-0.564l10.981-14.513c0.504-0.667,0.371-1.625-0.296-2.13
c-0.666-0.504-1.625-0.372-2.13,0.295l-8.354,11.042v-31.681c0-0.835-0.684-1.52-1.521-1.52c-0.835,0-1.52,0.685-1.52,1.52v32.117
L9.674,127.03c-0.541-0.638-1.506-0.717-2.144-0.176c-0.638,0.541-0.716,1.505-0.176,2.143l11.773,13.878
C19.551,143.373,20.229,143.525,20.81,143.313"/>
</svg>
My edited code:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="40px" height="150px" viewBox="0 0 40 150">
<style type="text/css">
.st0{fill:url(#s);}
</style>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="40" y2="150" >
<stop offset="0" style="stop-color:#FFCC07"/>
<stop offset="0.5111" style="stop-color:#346966"/>
<stop offset="1" style="stop-color:#51538C"/>
</linearGradient>
<rect fill="url(#SVGID_1_)" width="40" height="150"/>
<path fill="#FFFFFF" d="M20.811,143.313c0.349-0.07,0.676-0.258,0.906-0.563l10.981-14.513c0.504-0.668,0.37-1.625-0.296-2.131
c-0.666-0.504-1.625-0.371-2.131,0.295l-8.354,11.043v-31.682c0-0.835-0.684-1.52-1.521-1.52c-0.835,0-1.52,0.685-1.52,1.52v32.117
L9.674,127.03c-0.541-0.638-1.506-0.718-2.144-0.177c-0.638,0.541-0.716,1.506-0.176,2.144l11.773,13.878
C19.551,143.373,20.229,143.525,20.811,143.313"/>
</svg>
This image shows the differences:
file diff screenshot