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.