Rendering SVG shapes with crisp edges in IE9 - svg

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>

Related

SVG with 'svg' element embedded

I've a problem with a complicated SVG image.
It works on Chrome and Firefox, but there is no way to convert it into a PNG image even using an online tool or GIMP and also with Inkscape.
I'm not sure where the problem is. Maybe because is it an image built with two other SVG images embedded.
Here is the SVG file.
To reproduce the problem: open the SVG file linked with a browser: it works.
Open it with GIMP and the image is empty.
An easier example with the same problem:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<!-- Some graphical objects to use -->
<defs>
<svg id="pippo" viewBox="0 0 10 10" >
<circle id="myCircle" cx="5" cy="5" r="5" />
</svg>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop offset="20%" stop-color="gold" />
<stop offset="90%" stop-color="red" />
</linearGradient>
</defs>
<!-- Using my graphical objects -->
<rect height="100%" width="100%" fill="#fc0" />
<use x="0" y="0" href="#pippo" fill="url('#myGradient')" />
</svg>
With SVG 1 you need to use the attribute xlink:href instead of href on the use element
<use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
You will also need the xlink namespace on the <svg> element
<svg
viewBox="0 0 10 10"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
Since SVG 2, xlink: prefix is deprecated but SVG 2 is a W3C Candidate Recommendation and all its features are not yet supported by all browsers and editors.
Full SVG 1 example:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Some graphical objects to use -->
<defs>
<svg id="pippo" viewBox="0 0 10 10">
<circle id="myCircle" cx="5" cy="5" r="5" />
</svg>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop offset="20%" stop-color="gold" />
<stop offset="90%" stop-color="red" />
</linearGradient>
</defs>
<!-- using my graphical objects -->
<rect height="100%" width="100%" fill="#fc0" />
<use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
</svg>
Workaround: SVG to PDF via the native browser feature "save to PDF" (print modal)
Since Firefox, Chromium, and WebKit have powerful built-in PDF export functionalities combined with way better SVG support than any "desktop" application, we can convert complex SVG images to a flattened, 'visually hardwired' vector file.
Ideal result
all vector data is retained (can also be opened in a vector application like Inkscape, Adobe Illustrator, Figma, etc.)
complexities like nested SVG images or <use> elements as well as transforms are repositioned to hardcoded vector x/y coordinates.
... but curb your enthusiasm: common issues
patterns and some complex gradients might be rasterized
you will lose structural data like layers, IDs and other editable features.
Manual SVG export optimisations
as #Yukulélé already pointed out: some syntax conventions and newer attributes might be too progressive
try to replace CSS-based styling with attributes – svgomg can be helpful
reusable elements defined in <defs> or as <symbols> might have quirky recursive dependencies
try to clean up unnecessary or invalid properties (e.g., hexadecimal RGBA) and fix incomplete SVG nestings (missing end tags)
document dimensions and aspect ratios can often be better retained (by a graphic application),
when the parent SVG element was added a viewBox and width/height attributes (at least in Adobe Illustrator)

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.

SVG Xlink won't link to external file with xlink:href in <use> tag

I have two SVG files. I'm trying to xlink the contents of rect.svg into tst_use.svg. The contents of tst_use.svg are,
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xhtml="http://www.w3.org/1999/xhtml" version="1.1" id="svg_hom_img" width="508" height="438">
<use x="0" y="0" id="us_g1_0" width="508" height="438" xlink:href="rect.svg"/>
</svg>
and the contents of rect.svg are,
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xhtml="http://www.w3.org/1999/xhtml" version="1.1" id="svg_hom_img" width="508" height="438">
<rect x="0" y="1" width="250" height="250" id="BackDrop" pointer-events="all" style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2; stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"/>
</svg>
Of course, the two files are in the same directory. I have tried a number of combinations. The code works inline. rect.svg displays in the browser. I can also cobble the files together with javascript. Other people use this syntax. Why can't tst_use.svg xlink to rect.svg?
Using Robert Longson's comment, I changed test_use.svg to,
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xhtml="http://www.w3.org/1999/xhtml" version="1.0" id="svg_hom_img" width="508" height="438">
<use x="0" y="0" id="us_g1_0" width="508" height="438" xlink:href="rect.svg#BackDrop"/>
</svg>
with the same rect.svg as in the question. That displayed the rectangle in Firefox, but not in Chrome. It seems that javascript is the best solution.

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>

Svg image element not displaying in Safari

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.)

Resources