Svg image element not displaying in Safari - svg

Safari browser (I'm testing under windows) seems having problem in displaying Svg Image element.
<!DOCTYPE html>
<html>
<body>
<h1>My first SVG</h1>
<img src="image.svg" />
</body>
</html>
And here is the content of the image.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="50" y="50" width="100" height="100" style="fill:blue"></rect>
<rect id="foo" x="50" y="150" width="500" height="500" style="fill:green"></rect>
<image x="50" y="10" width="200" height="200" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="></image>
</svg>
Is there any solution or workaround to make this work in Safari?

In the <image> tag inside the svg element, href works fine in Chrome. To work in older versions of Safari, you need xlink:href. (Also applies to the <use> tag.) Keep in mind xlink:href is deprecated and is being replaced by href. However, it was not supported until Safari 12.
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/href
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ...>
<image href="data..." xlink:href="data...">
</svg>

I think there are two problems here:
You haven't said anything about how large your SVG image is. As a rule, you should at least include a viewBox attribute in the <svg> tag. For example:
<svg width="250" height="250" viewBox="0 0 250 250" ... >
The other problem is that Safari isn't particularly brilliant at rendering SVGs. However, it tends to do better when you embed them with an <iframe> or <object> tag instead of using <img>. For example:
<object data="image.svg" type="image/svg+xml"></object>
Also, make sure your server is delivering SVG content with the correct MIME type (Content-Type: image/svg+xml), as this can cause problems too.
So give this a try:
HTML source:
<!DOCTYPE html>
<html>
<body>
<h1>My first SVG</h1>
<object data="image.svg" type="image/svg+xml"></object>
</body>
</html>
image.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="250" height="250" viewBox="0 0 250 250"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="50" y="50" width="100" height="100" style="fill:blue"></rect>
<rect id="foo" x="50" y="150" width="500" height="500" style="fill:green"></rect>
<image x="50" y="10" width="200" height="200" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="></image>
</svg>

Be sure to supply your <svg> tag with a height, width, and view box like so. Safari doesn't like it when height or width is set to auto for some reason. ⤵︎
<svg height="16px" width="16px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M60......"></path></svg>

I just discovered this same problem when I checked an app I was working on in Safari, after having been using Chrome most of the time. I wrote this bit of TypeScript/jQuery code (easily enough turned into plain JavaScript) to solve the problem:
export function setSvgHref(elem: JQuery, href: string) {
elem.attr('href', href);
if (isSafari()) {
elem.each(function() {
this.setAttributeNS('http://www.w3.org/1999/xlink', 'href', href);
});
}
}

In my case, the problem was related to <mask> tags in svg.
I deleted the following line in my svg component and it started to work on Safari.
<mask id="y9iogdw0wd" fill="#fff">
<use xlink:href="#jz8vxv0q6c"/>
</mask>

I had a problem with a wordmark (text that I use as a logo) that I saved as a .svg file. It was on my page with a <img src="...svg"> but did not appear properly in Safari (current version as of July 2020). The SVG worked fine with FireFox, Chrome, and Brave.
I had created the SVG in Inkscape. I selected the entire object, then used Path -> Object to Path... and saved the resulting file.
This rendered properly in all four browsers. (I'm writing this here in case I have this problem again: it'll tell me what I did to fix it.)

Related

PNG inside SVG - not working in Firefox

I am trying to place a PNG image directly into the SVG file (using Base64). Here is a demo:
https://jsfiddle.net/bL11Lp8d/
<use href="#img1" transform="matrix(20,10,-5,20,50,50)" />
It works fine in Chrome, but does not work in Firefox. Do you know what is the problem?
The image has no width and height attributes. Firefox still requires them.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" width="500" height="500">
<defs>
<image id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" width="5" height="5" />
</defs>
<use href="#img1" transform="matrix(20,10,-5,20,50,50)" />
</svg>
SVG 1.1 says they are mandatory, The SVG 2 specification says optional.

How to set SVG fill using pattern in a different SVG file [duplicate]

The following attempt to make a rectangle with a pattern fill doesn't seem to work in Safari 6.1, Firefox 30, or Chrome 36, even though the W3 spec seems to say that a I can use a non-local IRI reference, including a relative one, like fill="url(localURL.svg#MyId)".
test.html
<html>
<head>
<style>
.patterned { fill: url("patterns.svg#polkadot");
stroke: lime; stroke-width: 5px}
</style>
</head>
<body>
<svg width="500" height="500">
<rect class="patterned" height="27" width="58">
</svg>
</body>
</html>
patterns.svg
<svg xml:space="preserve" width="225" height="110" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="polkadot" patternunits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<circle r="10" cx=12 cy=10 fill="purple">
</pattern>
</defs>
</svg>
Safari and Chrome show a black-filled green-outlined rectangle. Firefox shows an empty or white-filled green-outlined rectangle. None of them show the pattern of purple circles.
I'm trying this approach because I couldn't get an SVG fill pattern to work on Safari in the Backbone+JQuery+D3 project I'm working on using the most common method, an inline defs with fill="url(#MyId)". I couldn't get that approach to fail as a simple test case -- I thought I had, but that turned out to be a different Safari bug with an obvious workaround. At least that approach worked in some browsers.
You've a load of syntax errors in your patterns.svg file. Missing " characters round attribute values, an unclosed circle element, patternunits instead of patternUnits.
SVG standalone must be valid XML, it's not as forgiving as html and it's case sensitive on attribute names too. If you loaded the patterns.svg file directly, browsers would tell you all these things.
With all this fixed (as below) this works in Firefox. I'm not sure Chrome/Webkit have implemented this yet.
<svg xml:space="preserve" width="225" height="110" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="polkadot" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<circle r="10" cx="12" cy="10" fill="purple"/>
</pattern>
</defs>
</svg>

Render MathJax in an SVG file

I have spent a few days on the following with no joy.
I wish to render Mathjax in an SVG file. I have no problem including it in a html file in an svg element using a foreignObject from the examples at https://groups.google.com/forum/#!topic/mathjax-users/_UMt3C7TIpQ/discussion, but I cannot get it to work in an svg file.
The code I am trying is as follows :-
<svg width="1960" height="1080" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript" src="MathJax-master/MathJax.js?config=TeX-AMS_HTML-SVG"></script>
<g>
<title>Layer 1</title>
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="50" id="svg_1" y="223" x="636" stroke-opacity="0.8" stroke-width="0" stroke="#007FFF" fill="#000000">Hello World</text>
<foreignObject x="100" y="100" width="100" height="100">
<body xmlns="http://www.w3.org/2000/svg">
<div>
\(\displaystyle{x+1\over y-1}\)
</div>
</body>
</foreignObject>
</g>
</svg>
Any help would be much appreciated. I do suspect the problem is with the line declaring the body element.
A <div> tag is html so the <body> tag should be in the html namespace xmlns="http://www.w3.org/1999/xhtml" rather than the svg namespace.
Your other mistake is that you're using html syntax for the script tag. SVG script tags use xlink:href instead of a src attribute. Fixing that gets us here:
<svg width="1960" height="1080" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<script xlink:href="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<g>
<title>Layer 1</title>
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="50" id="svg_1" y="223" x="636" stroke-opacity="0.8" stroke-width="0"
stroke="#007FFF" fill="#000000">Hello World</text>
<foreignObject x="100" y="100" width="100" height="100">
<body xmlns="http://www.w3.org/1999/xhtml">
<div>
\(\displaystyle{x+1\over y-1}\)
</div>
</body>
</foreignObject>
</g>
</svg>
But when we do that we run into a bug in the mathjax library. It seems it expects to find html nodes in the document (check the Firefox Error Console). You'd have to contact the mathjax developers and get them to fix their bug to progress further.

Default background color of SVG root element

I'd like to set a default background color for the entire SVG document, to red for example.
<svg viewBox="0 0 500 600" style="background: red">/* content */</svg>
The solution above works but the background property of the style attribute is unfortunately not a standard one : http://www.w3.org/TR/SVG/styling.html#SVGStylingProperties, and so it gets removed during the cleaning process with SVG Cleaner.
Is there another way to declare this background color?
SVG 1.2 Tiny has viewport-fill I'm not sure how widely implemented this property is though as most browsers are targetting SVG 1.1 at this time. Opera implements it FWIW.
A more cross-browser solution currently would be to stick a <rect> element with width and height of 100% and fill="red" as the first child of the <svg> element, for example:
<rect width="100%" height="100%" fill="red"/>
Found this works in Safari. SVG only colors in with background-color where an element's bounding box covers. So, give it a border (stroke) with a zero pixel boundary. It fills in the whole thing for you with your background-color.
<svg style='stroke-width: 0px; background-color: blue;'> </svg>
It is the answer of #Robert Longson, now with code (there was originally no code, it was added later):
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red"/>
</svg>
This answer uses:
https://stackoverflow.com/a/11293812/6747994
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes
Let me report a very simple solution I found, that is not written in previous answers. I also wanted to set background in an SVG, but I also want that this works in a standalone SVG file.
Well, this solution is really simple, in fact SVG supports style tags, so you can do something like
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
<style>svg { background-color: red; }</style>
<text>hello</text>
</svg>
I'm currently working on a file like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/css" href="style.css" ?>
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 600 600">
...
And I tried to put this into style.css:
svg {
background: #bf1f1f;
}
It's working on Chromium and Firefox, but I don't think that it's a good practice. EyeOfGnome image viewer doesn't render it, and Inkscape uses a special namespace to store such a background:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
version="1.1"
...
<sodipodi:namedview
pagecolor="#480000" ... >
Well, it seems that SVG root element is not part of paintable elements in SVG recommandations.
So I'd suggest to use the "rect" solution provided by Robert Longson because I guess that it is not a simple "hack". It seems to be the standard way to set a background with SVG.
background and background-color are not widely supported
the shortest code without is to draw a circle with a radius of 10000, this does also work for width-height-aspect-ratios different to viewBox.
<circle r="1e5" fill="red"/>
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle r="1e5" fill="red"/>
</svg>
Another workaround might be to use <div> of the same size to wrap the <svg>. After that, you will be able to apply "background-color", and "background-image" that will affect thesvg.
<div class="background">
<svg></svg>
</div>
<style type="text/css">
.background{
background-color: black;
/*background-image: */
}
</style>

Rendering SVG shapes with crisp edges in IE9

IE9 appears not to honour the SVG shape-rendering="crispEdges" attribute.
Here's a sample SVG:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg" height="600" id="svgroot" version="1.1" width="800" x="0" y="0">
<line style="stroke:#000000;stroke-width:1px;stroke-opacity:1" y2="300" y1="300" x2="750" x1="50" shape-rendering="crispEdges" />
</svg>
It appears correctly under Firefox and Safari, however the line appears blured under IE9 and IE10 (Platform preview)
Is there some workaround to disable the anti-aliasing in IE9?
Thanks!
You should be able to just shift the line 0.5 "pixels" vertically instead of using shape-rendering. That way the line will look sharp in all non-IE browsers at least.
<svg xmlns="http://www.w3.org/2000/svg" height="600" width="800">
<line style="stroke:#000" y2="300.5" y1="300.5" x2="750" x1="50" />
</svg>

Resources