Gradients hidden using SVG symbols
Instead of display: none
, you can just use width="0" height="0"
.
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" style="display:block"> <defs> <style>.red-gradient{fill:url(#gradient)}</style> <linearGradient id="gradient" x1="0" x2="0" y1="0" y2="1"> <stop offset="0%" stop-color="red"/> <stop offset="100%" stop-color="darkred"/> </linearGradient> </defs> <symbol id="mysymbol" viewBox="0 0 100 100"> <circle class="red-gradient" cx="0" cy="50" r="50" /> <circle fill="green" cx="100" cy="50" r="50" /> </symbol> </svg>
<svg><use xlink:href="#mysymbol" /></svg>
Hide svg used for gradient
You can add these to your gradient svg style rules
visibility: hidden;
position: absolute;
It will hide your svg, and take that svg element out of your page flow so it will not occupy any pixels on your page
SVG LinearGradient hidden if svg is hidden in seperate class
Either consider a different ID for the gradients:
.mobile { display: none;}
.content-svg { border: 1px solid black;}
<div class="desktop"> <!-- stuff here --></div>
<div class="mobile"> <svg class="mobile-svg" height="150" width="400"> <defs> <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" /> </linearGradient> </defs> <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" /> Sorry, your browser does not support inline SVG. </svg></div>
<div class="content"> <svg class="content-svg" height="150" width="400"> <defs> <linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" /> </linearGradient> </defs> <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" /> Sorry, your browser does not support inline SVG. </svg></div>
How can I refer to an internal gradient definition inside an SVG sprite symbol?
Firstly please note the edit to my question - whereupon I discover that the use of display: none
to hide the SVG symbols until we need them was the problem.
I kept fiddling and settled upon this "answer", which is far from perfect, but should still be reliable for any such situation.
All you need to do is wrap the entire <svg>
code in a <div>
container which must be displayed but will never affect layout, so I've just done this via mega overkill CSS such as:
height: 0; width: 0; position: absolute; visibility: hidden;
And this works great. See the final fiddle: http://jsfiddle.net/Qtq24/5/
If anyone has a better solution, I'd love to hear it as this feels like a bit of a hacky way of doing it but I guess no more hacky than having to use display: none;
anyway.
linearGradient not working for SVG sprites
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>
How to hide svg from the page?
The default value for the width and height attributes on the svg
element is 100%, which means the SVG viewport depends on the parent container it's in.
From the w3 spec:
The SVG user agent negotiates with its parent user agent to determine the viewport into which the SVG user agent can render the document.
To solve your issue you can set the width and height attributes to 0
directly on the svg
tag, but it's also possible to use CSS.
To prevent svg
elements to take up space on the page use display: none
. I'm not sure about browser support of gradients in this case, but there are work arounds. Check this Bugzilla post.
Related Topics
Different Timing Functions for Different Parts of CSS3 Keyframe Animation? (Accurate Bounce)
Convert Internal Stylesheet to Inline CSS
Sass/Scss @Extend Rule Selectors
Is It Ok to Use Cellpadding="2" Cellspacing="2" in <Table>
Not (Max-Width: 512Px) Not Working
Remove Unwanted Space with Position Sticky
Do CSS Variables Work Differently in Microsoft Edge
CSS Inverted Trapezium When Width Will Differ
Background-Image Doesn't Appear If <Div> Is Empty
Jquery-Ui Datepicker CSS Problem
IE8 Renders Font Weights Randomly
Did Chrome 40 Break Justify-Content CSS Overriding
Why Is "Rgb (224, 226, 213)" an Invalid Property Value
Give a CSS Styled Div a "Border-Left-Image"
What's the Point of the ::Before and ::After Pseudo-Element Selectors in CSS