I'm including an inline SVG on my webpage and inside that SVG I have a <use> to another SVG. Due to a timing bug where sometimes that use-svg has a wrong rotation what I noticed is that the <use> has width and height 0 when it's still loading the external SVG, even though I set the width and height on the <use> tag.
Having this as 0 causes problems on the rotation and subsequent processing. If I wait for it to load all is well.
(this was tested in Chrome 85.0.4183.121 and Firefox 81.0b2)
I find this strange because if I use an <image> to get my external SVG it loads the dimensions I specify when it's loading.
<use id="SvgjsUse1044" xlink:href="/images/checkmark.svg#Layer_1" width="8" height="8" x="26" y="-4"></use>
checkmark image:
<?xml version="1.0" encoding="utf-8"?>
<!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="8px" height="8px" viewBox="0 0 8 8" enable-background="new 0 0 8 8" xml:space="preserve">
<path fill="#FFFFFF" d="M6.769,0.5L8,1.901L4.307,6.099L3.076,7.5L1.849,6.099L0,4l1.231-1.401l1.845,2.099L6.769,0.5z"/>
</svg>
I just want it to behave as <image> does :) I'm fully aware I can change the logic of the app to wait for it to load but it has a lot of other consequences.
Is there any way to force the browser to understand and follow the width/height of a <use> element while loading?
I'm trying to embed a set of SVG images in a blank web page.
<html><head></head>
<body>
<img width="117px" src="img/icone/phone_hex034F84.svg" alt="image">
<img width="320px" src="img/illustrazioni/SHIPPER3.svg" alt="image">
</body>
</html>
Both files are self-contained svg generated by Illustrator.
While the first does render in the browser the second (SHIPPER3.svg) doesn't.
See the code: http://104.155.112.173/land/img/illustrazioni/SHIPPER3.svg
You can download the full source from the previous link as I cannot embed it in the question (too large). Although, I'll embed here just the preamble.
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="_x5B_SHIPPER1_x5D_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 733.3 587.8" style="enable-background:new 0 0 733.3 587.8;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);}
.st1{fill:#EDEDED;}
.st2{fill:#F2F2F2;}
If I copy and paste SHIPPER3.svg in http://www.freecodeformat.com/svg-editor.php it does render. I can also open it in Sketch with no problems.
I tried to embed SHIPPER3.svg also as inline svg but same, again, no show.
What I am missing?
Several problems in your SHIPPER3.svg:
all your top-level groups has class st0 which is said to be clipped out by clipPath that is outside entire viewBox
clipPath #SVGID_2_ has style="display:none;" what also hides it
See:
<svg version="1.1" viewBox="0 0 733.3 587.8">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);}
/* ... */
</style>
<defs>
<ellipse id="SVGID_1_" cx="1085.6" cy="279.3" rx="251.8" ry="233.4"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="display:none;overflow:visible;"/>
</clipPath>
<g class="st0">
<!-- ... -->
</g>
</svg>
Further to a comment I left above, you may wish to replace the <clippath id='SVGID_2_' element with the following:
<clipPath xmlns="http://www.w3.org/2000/svg" id="SVGID_2_">
<ellipse xmlns="http://www.w3.org/2000/svg" id="SVGID_1_" cx="360" cy="290" rx="325" ry="260"/>
</clipPath>
This does 2 things. (0) it removes the link to the SVGID_1_ element by inserting the data that was inside it directly. (1) repositions and sizes the ellipse
I would like to know more about svg and I have a question.
For exemple, I've export a shape with Illustrator as html code so I have this :
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.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="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1920 600" enable-background="new 0 0 1920 600" xml:space="preserve">
<g>
<polygon fill="none" stroke="#B24539" points="0,297 0,379.3 26.9,346.1 "/>
</g>
And I want to know the difference between using svg with code like this and using an image.svg ?
Inline SVG would allow you to target parts of your SVG with CSS:
.svg {
fill: #fff;
}
This is not possible if the SVG was brought in with an <img> tag.
Here's a post from CSS Tricks that talks about the many different ways you can use SVGs: https://css-tricks.com/using-svg/
It would be best to use inline svg as #restlessbit points out, because you have more control over the style.
For example, changing background colors, adding path colors and even adding text to an SVG can be done when adding SVG inline.
Here is a post that illustrates some of these mentioned benefits to using inline SVG in case you wanted some more info: https://viget.com/extend/getting-started-with-inline-svg
I just received an SVG file which I want to include into my HTML code.
Everything is working properly, except that Firefox somehow just renders the font int the SVG extremely bad.
Here's two screenshots:
Opera/Chrome -> perfectly fine
Firefox -> awful
I searched for about two hours now and didn't find any useful hints at all.
What could the reason be?
Thanks in advance
Edit:
Here's the XML Code from the file.
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, 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="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="98px" height="139px" viewBox="0 0 98 139" enable-background="new 0 0 98 139" xml:space="preserve">
<image overflow="visible" width="98" height="139" xlink:href="data:image/jpeg;base64,/9j/4AA....." transform="matrix(1 0 0 1 0 0)">
</image>
</svg>
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.