Chrome seems not to display <use> elements in inline svg. Here is an example (code below or view it at http://www.bobwyttenbach.com/chromeuse.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chrome use-tag bug?</title>
</head>
<body>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
<defs>
<g id="test1">
<circle cx="100" cy="100" r="50" fill="red"/>
</g>
</defs>
<g>
<rect x="0.5" y="0.5" width="199" height="199" stroke="black" fill="none"/>
<use xlink:href="#test1" x="0" y="0"/>
</g>
</svg>
<p>Above is inline svg with a use tag; below is the same svg linked through an object tag. Below is correct.</p>
<object data="chromeuse.svg" width="200" height="200"></object>
</body>
</html>
The red circle does not appear in the inline svg but does appear when the same svg is linked through an object tag. Safari, Firefox, Opera, and Internet Explorer 9 all display the inline svg correctly.
Am I doing something wrong? Is this a known Chrome bug (I haven't found it listed)? Any workarounds?
Don't know if this question is still relevant, but I've met such a case recently and I pretty sure that somebody else will meet the case (especially those who tries to make use of SVG sprites for the first time).
In my case I've joined 16 SVG icons in one sprite manually into sprite.svg, and in this file I've omitted important meta information:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
I had no first line at all, and all I had on the second line was an opening <svg> tag with no meta attributes (xmlns and xmlns:xlink). As soon as I brought back all this omitted meta information, my graphics from sprite.svg started to display properly.
Hope it helps someone.
Ok so I deleted my last post as I incorrectly tried to figure out why the use element was working for me and not for you. What I can say is that I am using a modified version of this source, https://code.google.com/p/svg-edit/ , so in short, my answer is to walk through and see how they do it. I believe its demonstrated when you insert an image from their library.
I spent a long time debugging inline svg use elements not showing up. The chrome bug discussed by BobW seems fixed at this time. To eliminate the same issue caused by something else entirely, try commenting out the <base href="somethingsomethingsomething" /> tag from your HTML.
Of course, this will likely break every relative link on your site, but the <use> elements now show up. One step forward, half a step back :)
Related info here:
Using base tag on a page that contains SVG marker elements fails to render marker
Related
Is there a way to fix the HTML validation error? While keeping using the SVG as the source code of the <img> tag?
Error: Bad value data:image/svg+xml;utf8,<svg
xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'></svg>
for attribute src on element`
My source code:
<img alt="homepage" src="data:image/svg+xml;utf8,<svg
xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'></svg>"
/>
To use an SVG as a data URI within an <img> element, the SVG code needs to be escaped:
<img alt="homepage" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'%3E%3C/svg%3E">
There are several free tools for doing this, such as URL-encoder for SVG.
If you want a non-interactive svg, use with script fallbacks to png version (for older IE and android < 3). One clean and simple way to do that:
<img src="your.svg" onerror="this.src='your.png'">
your.svg being the path to your svg.
This will behave much like a GIF image, and if your browser supports declarative animations (SMIL) then those will play.
If you want an interactive svg, use either <iframe> or <object>.
If you need to provide older browsers the ability to use an svg plugin, then use <embed>.
For svg in css background-image and similar properties, modernizr is one choice for switching to fallback images, another is depending on multiple backgrounds to do it automatically:
div {
background-image: url(fallback.png);
background-image: url(your.svg), none;
}
An additional good read is this blogpost on svg fallbacks.
For inline SVG; <svg> tags can be inserted as <svg> elements directly into the HTML and not part of the <img> tag. As it is inline SVG the <img> tag is pretty redundant as all the required parameters can be held inside the <SVG>.
Read about it here
Example:
<html>
<head>
<title>SVG Demo</title>
</head>
<body>
<svg
viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice"
style="width:35%; height:35%; position:absolute; top:0; left:0; z-index:-1;">
<linearGradient id="gradient">
<stop class="begin" offset="0%"/>
<stop class="end" offset="100%"/>
</linearGradient>
<rect x="0" y="0" width="100" height="100" style="fill:#cc9966;" />
<circle cx="50" cy="50" r="30" style="fill:#f9f333;" />
</svg>
</body>
</html>
I'm building an icon solution using SVG, where parts of icons need to be reusable. There are a few different <svg /> elements inline in my HTML document, and the <use /> element works perfectly for reusing shapes – rects, paths and so on, even between svg elements.
However, reusing other definitions, like <radialGradient /> doesn't work for me. When the gradient is defined within a <defs /> element in the same <svg /> element, it works as expected, but not when the gradient is defined in another <svg /> element.
Pseudo code
<!-- Near the top of my BODY element -->
<!-- This is where I keep the SVG stuff I want to reuse -->
<svg id="for-reuse" style="display:none">
<defs>
<path id="marker" d="M63 127L49 93C44 80 52 69 63 69L64 69C75 69 83 80 78 93L64 127" />
<radialGradient id="shadow">
<stop offset="10%" stop-color="rgba(0,0,0,0.4)" />
<stop offset="90%" stop-color="rgba(0,0,0,0)" />
</radialGradient>
</defs>
</svg>
<!-- Further down the html document -->
<svg viewBox="0 0 128 128" style="width:64px; height:64px" xmlns="http://www.w3.org/2000/svg" version="1.1">
<!-- This use element works fine! -->
<use xlink:href="#marker" style="fill:black" />
<!-- But this fill attribute does not! -->
<rect x="5" y="5" width="20" height="20" fill="url(#shadow)" />
</svg>
Why is it possible to use shapes from other svg elements, but not attribute values like this? When I move the shadow gradient into a defs element inside the visible svg element, the reference works perfectly.
Here is a JSFiddle that illustrates both working and non-working: https://jsfiddle.net/7tfna0L8/2/
The solution
Robert Longson pointed out that my "repository" of reusable svg had a style of display:none. For me, that feels like the correct way to do this. After all, this repository should not be displayed in any way. The problem is that the browser optimizes this by probably not even parsing any style at all, which makes it possible to reference elements, but not style (like my gradient)
Working jsFiddle: https://jsfiddle.net/atornblad/7tfna0L8/3/
Your far-gradient is in an svg which has a style of display:none. That disables all CSS within that fragment so it doesn't work. Try width="0" height="0" instead of display:none.
Our svg icons included using the img tag are getting incorrectly resized, cut off, or completely hidden when displayed in IE9.
The solution in https://gist.github.com/larrybotha/7881691 (setting the viewBox, removing width and height) does not help and neither does including the images as background.
When included using the tag, the SVGs display properly (but then they do not display in some modern browsers like chrome)
One of the icons we use has the following source:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generated by IcoMoon.io -->
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 640 640">
<metadata id="metadata167">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path id="path161" fill="#c6c6c6" d="m227.88,640.44c-19.924,0-38.795-9.298-50.887-25.329l-163.69-216.1c-21.298-28.12-15.756-68.15,12.367-89.45,28.169-21.34,68.155-15.76,89.456,12.37l107.68,142.17,270.79-434.72c18.64-29.909,58.03-39.07,87.98-20.428,29.91,18.596,39.07,58.032,20.39,87.942l-319.85,513.45c-11.13,17.909-30.321,29.131-51.345,30.047-0.96187,0.0458-1.9237,0.0458-2.8856,0.0458z" stroke="#c6c6c6"/>
</svg>
Any idea on what we could do to make SVG render properly in IE9?
I can't be sure that this will answer your question without seeing the specific code you're having problems with, Jakub. But I always include the following attributes in every SVG element, as a minimum. This always gives me a good level of cross-browser consistency, back to IE9:
<svg height="40" version="1.1" viewBox="0 0 40 40" width="40" xmlns="http://www.w3.org/2000/svg">
If that doesn't help, could you share your code?
Wrapping the svg into a div and giving that a width seems to work fine for me.
http://codepen.io/anon/pen/qONXzz
.svg-test{
width: 50px;
}
It seems that the only method for embedding and resizing an external xml file that works correctly in all browsers is the one described in http://edutechwiki.unige.ch/en/Using_SVG_with_HTML5_tutorial
So instead of
<img src="./images/icons/icons-complete.svg" style="width: 11px;height:11px;"/>
you can use
<svg height="11" width="11"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="scale(0.0172)">
<image x="0" y="0" height="640" width="640" xlink:href="/images/icons/icons-complete.svg"/>
</g>
</svg>
I'm trying to make a SVG icon sprite, something like in this fiddle
http://jsfiddle.net/8ke8nsft/6
Only difference is on my app I use a relative URL "../images/svg-sprite.svg#home-icon" this works great on chrome and safari, but doesn't show up on firefox.
<svg class="home-icon">
<use xlink:href=../images/svg-sprite.svg#home-icon"/>
</svg>
Firefox works perfectly when I add the svg sprite inline on top of the page then use it
<svg class="home-icon">
<use xlink:href=#home-icon"/>
</svg>
and this is my SVG file
<svg>
<symbol id="home-icon" viewBox="0 0 512 512">
<title>Home Icon</title>
<path d="M512,296l-96-96V56h-64v80l-96-96L0,296v16h64v160h160v-96h64v96h160V312h64V296z"/>
</symbol>
</svg>
am I missing something here?
In order to better protect your security, Firefox only allows files to refer to other files if they are in the same directory or a sub-directory of the original file.
If you access content via a web-server then this restriction does not apply, however the web-server may impose other restrictions on file location.
I found my self troubled with this issues. I just realised that I'm missing xmlns="http://www.w3.org/2000/svg" from external svg file. So try to:
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="home-icon" viewBox="0 0 512 512">
<title>Home Icon</title>
<path d="M512,296l-96-96V56h-64v80l-96-96L0,296v16h64v160h160v-96h64v96h160V312h64V296z"/>
</symbol>
</svg>
And I think you would be fine
Please make sure you're running html in webserver. Directly it will not work.
Example:
Running it in webserver will work:
http://localhost/test/home/home.svg.html
Running without webserver will not work:
file:///C:/wamp64/www/test/home/home.svg.html
Further, please use "href" tag instead of "xlink:href". href tag is being deprecated with SVG2.
https://www.w3.org/TR/SVG2/linking.html
So new tag would be:
<svg>
<use href="home.svg#home-icon"> </use>
</svg>
In my document, I was missing a closing SVG tag. Worked in other browsers, but not Firefox. Fixing the problem SVG tag solved the issue, so check your source document to make sure it's valid SVG.
The attribute xlink:href is missing the first ' " '.
Inside my website, I am embeding a few svgs. They all seem to work just fine in Chrome, Firefox, IE(9+) and in Safari. Howvere as soon as there is image included in the svg, safari does not render the image.
Based on the previous similar topic I have tried the following:
SVG <image> elements not displaying in Safari - enclosing
<use>
tag like this <use></use>
SVG Image dosen't appear in Safari - I dont find this very usefull,cause this is deleting aprt of the svg.
Not able to render SVG image in Safari - Added
<meta http-equiv="Content-Type" content="application/xhtml+xml"> in header.
And beyond that, I dont really know what else to try. Maybe one more interesting thing to note is that inside my page, image is not displayed, but I can open svg file in safari(just the file) and it will be renderd correctly. Further more, after it's opened in the browser as a file, it renders inside the page as well. And I embed the svg to the page with img tag.
<img src="mysvg.svg" class="center-block"/>
This is my svg:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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="328px" height="328px" viewBox="0 0 328 328" enable-background="new 0 0 328 328" xml:space="preserve">
<g>
<defs>
<polygon id="SVGID_1_" points="1.414,164.001 164,326.586 326.586,164.001 164,1.414 "/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"></use>
</clipPath>
<g id="DSC_x5F_0112-2.psd" clip-path="url(#SVGID_2_)">
<g id="DSC_x5F_0112-2.psd_1_" enable-background="new ">
<image overflow="visible" width="338" height="532" id="DSC_x5F_0112-2" xlink:href="data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QNhaHR0cDov
.....SLKPF+7j+acOZPZjmsw4Q0f0L/6k1fu3WFvY/wDEB5o0d7H7/wD7SPFgPzVE54J9/wBI/qez5vei
r/fdeaS//9k=" transform="matrix(0.9818 0 0 0.9818 -2.7197 -11.064)">
</image>
</g>
</g>
</g>
<g>
<path fill="#FFFFFF" d="M164,328.001L0,164.002L164,0.001l164,164.001L164,328.001z M1.414,164.002L164,326.587l162.586-162.585
L164,1.415L1.414,164.002z"/>
</g>
</svg>
I have reduced base64 image string, to shorten the code. Full svg can be found here.
UPDATE: Just to be clear, svg shows in the browser(safari) but image is missing (I can see just border).
It looks like this WebKit bug is responsible for the problem: https://bugs.webkit.org/show_bug.cgi?id=99677
The workaround we use in our application is to have a script which finds all img elements displaying SVG images and add hidden object elements loading the same SVGs (<object style="position: fixed; width: 0; height: 0;" data="image.svg" type="image/svg+xml"></object>).
The reason it works is that the object tag properly loads the embedded images into the image cache, so that they are visible within the SVGs loaded using the img tags.
The advantage of this approach is that the images are still displayed using the img tag, so that the workaround can be applied (and later removed cleanly when the browsers are eventually patched) without affecting the rest of the application/website.
The disadvantage is the creation of an extra object tag for each SVG image.
This solution works for me when displaying an embedded SVG image in Safari.
replace
<img src="image.svg">
with
<object data="image.svg" type="image/svg+xml"></object>
I ran into this problem where I was using Ajax to load the svg spritesheet onto the page. If I had a on the page before the spritesheet was loaded, it would fail and would not resolve once the spritesheet was avaialble. Any added to the dom after the spritesheet was loaded were fine. I had to delay putting the items in the dom until after the spritesheet finished loading.
This only affected IOS. All other browsers didn't care about the order.
It seems that answer from this question works: What could make Safari skip clip-path AND mask with SVG?. See instructions in link from answer.
You have to recreate your clip path to make it visible. And </clippath> tag is not pushed after </image> tag.
Here is the little changed code (link to my image inserted so you will have to change it):
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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="328px" height="328px" viewBox="0 0 328 328" enable-background="new 0 0 328 328" xml:space="preserve" >
<g>
<clipPath id="SVGID_2_">
<!--use xlink:href="#SVGID_1_" overflow="visible"></use-->
<polygon id="SVGID_1_" points="1.414,164.001 164,326.586 326.586,164.001 164,1.414" />
</clipPath>
<defs>
<polygon id="SVGID_1_" points="1.414,164.001 164,326.586 326.586,164.001 164,1.414"/>
</defs>
</g>
<image clip-path='url(#SVGID_2_)' overflow="visible" width="338" height="532" id="DSC_x5F_0112-2" xlink:href="images/banner_03.jpg" transform="matrix(0.9818 0 0 0.9818 -2.7197 -11.064)">
</image>
<g>
<path fill="#FFFFFF" d="M164,328.001L0,164.002L164,0.001l164,164.001L164,328.001z M1.414,164.002L164,326.587l162.586-162.585
L164,1.415L1.414,164.002z"/>
</g>
</svg>
So Anto Jurković pointed out, there are some known issues with Safari and clipPath. What Safari likes is if you dont define polygon but put it straight in to clippPath. Also you must then group clipPath separately.
But I still could not get svg to render the image if I used img tag for svg - <img src="svg"/>. So at the end I have embeded it like this:
<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="328px" height="328px" viewBox="0 0 328 328" enable-background="new 0 0 328 328" xml:space="preserve">
<g>
<clipPath id="SVGID_2_">
<polygon id="SVGID_1_" points="1.414,164.001 164,326.586 326.586,164.001 164,1.414 "/>
</clipPath>
</g>
<image clip-path="url(#SVGID_2_)" overflow="visible" width="338" height="532" id="DSC_x5F_0112-2" xlink:href="data:image/jpeg;base64,/9j/.....r/fdeaS//9k=">
</image>
<g>
<path fill="#FFFFFF" d="M164,328.001L0,164.002L164,0.001l164,164.001L164,328.001z M1.414,164.002L164,326.587l162.586-162.585
L164,1.415L1.414,164.002z"/>
</g>
</svg>
I can confirm that this renders correctly in mobile safari(on ipad and iphone, windows safari and mac safari - latest versions).
So to sum it up...I have this svgs in separate html file and render them when needed.