PNG inside SVG - not working in Firefox - svg

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.

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)

SVG <defs> not included from external target of <use> [duplicate]

I'm trying to hack together a sprite sheet from a set of icons. I know almost nothing about SVG. I can get the simple icons to work, but an icon with a clip path isn't displaying properly. From what I can tell it seems like it's not using the clip path.
The sprite works in jsfilddle and it works if I just load the svg on it's own and include a < use > statement in the SVG. But if I have a separate < use > it doesn't work.
All my testing has been done in Chrome (50.0.2661.94)
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<clipPath id="folder-clip-0">
<path d="..." />
</clipPath>
<symbol id="folder" viewBox="0 0 32 32">
<g class="container" data-width="32" data-height="27" transform="translate(0 2)">
<path d="..." class="..." />
<path class="..." d="..." />
<path clip-path="url(#folder-clip-0)" d="..." class="..." />
</g>
</symbol>
</defs>
</svg>
I'm using it like so:
<svg>
<use
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="/img/path/sprite.svg#folder">
</use>
</svg>
When I use the separate statement it looks like this:
But it should look like this:
The color difference is not relevant, it's just the background when the image was taken.
Edit:
I just discovered that if I dump the whole sprite sheet into the page HTML and reference it locally instead of an external file it works. So I don't know what's wrong with my external reference.
e.g.
<svg>
<use xlinkHref={"/img/path/not/work/sprite.svg#folder"}></use>
</svg>
vs.
<svg>
<symbol id="folder"></symbol>
</svg>
<svg>
<use xlinkHref={"#folder"}></use>
</svg>
This works for me as a fallback, but I'd rather have an external SVG file instead of embedding it in my HTML.
Edit 2:
If the SVG sprite sheet is embeded in the HTML directly using the external link shows the icon correctly.
This seems to be a browser support issue. Using the external reference works as expected in Firefox. Chrome doesn't handle clip paths and some other functions in external references. There's an outstanding bug report filed. Safari also doesn't support it.
Related StackOverflow ticket: Why can't I reference an SVG linear gradient defined in an external file (paint server)?
Open bugs:
https://code.google.com/p/chromium/issues/detail?id=109212
https://bugs.webkit.org/show_bug.cgi?id=105904

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 use linked from an external source not showing svg data

I have an html page with two svg use elements:
The first references inline svg.
The second references an external svg file (same code).
I am trying to figure out why the second example does not show the svg paths even though the SVG code that is inline is exactly the same as the SVG code in the linked file.
https://s3.amazonaws.com/jagger/svg/index.html
<svg class="svg-inline">
<use xlink:href="#test" />
</svg>
<svg class="svg-external">
<use xlink:href="sprite.svg#test" />
</svg>
<svg width="0" height="0">
<symbol id="test" viewBox="0 0 600 600">
<title>Test Icon</title>
<rect id="svg_2" height="214.39594" width="481.62782" y="10" x="10" stroke-width="5" stroke="#000000" fill="none"/>
<line fill="none" stroke="#000000" stroke-width="5" x1="10" y1="10" x2="400" y2="400" id="svg_1"/>
</symbol>
</svg>
using of external sprite is working in the latest version of all modern browsers
still problem in actual IE and older browsers versions
see MDN <use> browser_compatibility table
for IE (and older browsers) just use polyfill svg4everybody

How to reuse <image> tags in SVG <defs>?

I have a situation where to save on memory and loading, I am trying to reuse a single <image> tag in an SVG, instead of referencing the same xlink:href in several <image> tags.
My research has shown that <use> is the tag to reference a defined object.
However, when I try to reference an image, particularly inside a pattern (which is what I am trying to do), I get nothing, where using an image tag works fine.
What am I doing wrong? Is this even possible? I tried searching, but could not find any examples of the <use> tag with an image, just rects, paths, groups, etc.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 1024 600" >
<style type="text/css">
.fillme{fill:url(#tsmall)}
</style>
<defs>
<image id="texture" xlink:href="texture.tiny.png" />
<pattern id="tsmall" patternUnits="userSpaceOnUse" width="486" height="402">
<use xlink:href="#texture" x="0" y="0" width="486" height="402" />
</pattern>
<pattern id="tlarge" patternUnits="userSpaceOnUse" width="972" height="804">
<use xlink:href="#texture" x="0" y="0" width="972" height="804" />
</pattern>
</defs>
<rect x="0" y="0" width="1024" height="600" class="fillme"/>
</svg>
SVG image elements must have width and height attributes, yours doesn't.
An image is a graphics element and if you point a <use> at a graphics element the <use> width and height are ignored per the SVG specification (since it's not a symbol or an svg element it falls into the Otherwise case in the specification)

Resources