SVG Linked from same svg file causes one to disappear - html

Strange one this.
I've got the following:
<svg aria-hidden="true">
<use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#down"></use>
</svg>
<table>
<tr>
<td>
<svg aria-hidden="true">
<use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#close"></use>
</svg>
</td>
</tr>
</table>
The first icon doesn't show up. However if I change the svg file of the first to:
<svg aria-hidden="true">
<use xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#down"></use>
</svg>
Then both show, is there something I'm missing with SVG from the same file?
It's definitely not a URL thing, because if both <svg> tags use the same URL, then only the second is displayed.
Many Thanks

HOPE THIS HELPS TO ALL NEW PEOPLE
After all this years I stumbled upon the same problem and I solved it...
What happened for me was that the fill attributes of my paths shared the same url(#paint0_linear) and the viewbox of these "fill" where set on the position of the first SVG in the DOM, to solve this just change the name of the fills (and their corresponding id's) of the subsequent SVGS.
English is not my native language so let me show you what I did in code in case I didn't make myself clear:
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="hamb1">
<path id="hambBottom1" fillRule="evenodd" clipRule="evenodd" d="M0 22" fill="url(#paint0_linear)"/>
<path id="hambTop1" d="M13.8599" fill="url(#paint1_linear)"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="-6.5" y1="30" x2="18.9429" y2="34.8415" gradientUnits="userSpaceOnUse">
<stop stopColor="#134F82"/>
<stop offset="1" stopColor="#2BA665"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="-6.50012" y1="30" x2="18.9428" y2="34.8414" gradientUnits="userSpaceOnUse">
<stop stopColor="#134F82"/>
<stop offset="1" stopColor="#2BA665"/>
</linearGradient>
</defs>
</svg>
Check that the fill attribute on the paths NEVER share the same id.

I can't be completely sure since I guess you should explain question properly, But it may be the case that first file path may not be correct (ie with link "/assets/icons/utility-sprite/svg/symbols.svg#down") (ie may be some spell error) so the file is not loading. Try loading file manually with url.

Related

Why doesn't this SVG display?

I'm working on a project that uses svg. I generate this svg code thanks to an ocaml library:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:l="http://www.w3.org/1999/xlink" version="1.1" width="161.8mm" height="100mm" viewBox="0 0 161.8 100" color-profile="auto" color-interpolation="linearRGB" color-interpolation-filters="linearRGB">
<g fill="none" stroke-miterlimit="9.98123" transform="matrix(100 0 0 -100 -0 100)">
<defs>
<path id="i1" d="M0 0L1.618 0L1.618 1L0 1Z"/>
</defs>
<use l:href="#i1" fill="#50C878"/>
</g>
</svg>
When I use gthumb or GIMP to display the svg, it prints the correct green square. However, when I include this block of code in Chromium or Firefox, the block appears in the html tree but nothing is display. This is the first time I use svg: after several researches on Google, I can't find anything....
Does someone know why it doesn't work ?
Edit
Solve with the answer:
<use xlink:href="#i1">

SVG <linearGradient> code keeps breaking when rendered in any browser

I've scoured all corners of the web looking for a solution to this but it seems no one else has had this issue.
Here is my current code:
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="mygradient">
<stop offset="0%" stop-color="red"/>
<stop offset="100%" stop-color="yellow"/>
</linearGradient>
</defs>
<path id="myID" d="M 0 78.37136556477951 C 207.875 51.32892778872315 207.875 51.32892778872315 415.75 64.85014667675132 C 623.625 78.37136556477951 623.625 78.37136556477951 831.5 60.035876993171016 C 1039.375 41.70038842156255 1039.375 41.70038842156255 1247.25 64.68862384088634 C 1455.125 87.67685926021014 1455.125 87.67685926021014 1663 60.035876993171016 L 1663 3756 L 0 3756 Z" fill="url(#mygradient)"/>
</svg>
Whenever any browser tries to render this, the <linearGradient> breaks completely. This is how it renders in browsers:
<lineargradient id="mygradient"><stop offset="0%" stop-color="red"></stop offset="0%" stop-color="red"><stop offset="100%" stop-color="yellow"></stop offset="100%"></lineargradient id="mygradient">
As you can see, all spaces in the <linearGradient> become and <linearGradient> becomes <lineargradient>.
Any help with this will be appreciated.
Sorted this one out, pasted my <linearGradient> code snippet into a minifier which seemed to fix the issue. Don't know why but it just did.

SVG clipping path scaling

I am currently trying to get an image with an SVG clipping path to scale with the browser (image needs to be 100% of browser width). I have read in several places that applying both clipPathUnits="objectBoundingBox" and transform="scale(0.01)" is the solution, however I am unable to get this to work. Whenever I apply those, the image disappears.
No doubt something simple I'm missing?
Codepen
HTML
<img id="preview-img" width="100%" src="http://www.menucool.com/slider/prod/image-slider-4.jpg" style="clip-path: url("#clipPolygon");" class="moving">
<svg width="0" height="0" >
<clipPath id="clipPolygon" clipPathUnits="objectBoundingBox" transform="scale(0.01)">
<polygon id="poly1" points="317 343,966 254,964 -6,610 -5">
<animate id="poly1Anim" attributeName="points" dur="500ms" to="" fill="freeze" />
</polygon>
</clipPath>
</svg>
If you remove the two attributes mentioned above, the image shows, however I require the image and path to scale with the browser.
Choosing the right scale:
As clipPathUnits="userSpaceOnUse" uses the size of the original path (in absolute pixels) and clipPathUnits="objectBoundingBox" uses 0 to 1 as the coordinate system, the correct scale is
scale(1/x, 1/y)
So for a svg with coordinates meant for a 1280x800 px image, the correct scale would be:
scale(0.00078125, 0.00125)
Turns out the solution was the simple case of adjusting the scale from 0.01 to 0.001!
Updated working codepen
<img id="preview-img" width="100%" src="http://www.menucool.com/slider/prod/image-slider-4.jpg" style="clip-path: url("#clipPolygon");" class="moving">
<svg width="0" height="0" >
<clipPath id="clipPolygon" clipPathUnits="objectBoundingBox" transform="scale(0.001)">
<polygon id="poly1" points="317 543,966 254,964 -6,610 -5">
<animate id="poly1Anim" attributeName="points" dur="500ms" to="" fill="freeze" />
</polygon>
</clipPath>
</svg>

SVG Rounding Bug

Chrome's way of rounding sub-pixel values in SVGs creates a problem for me.
Is there any way to fix this problem? Because I use opacity I'm not able to simply add a dark background to remove the white glimps.
Here's the example:
http://dabblet.com/gist/766f6a238d00bcbb41d4
You can create a filter to add "grout" into the gap :) But it's a hack that works by increasing the opacity of those pixels. It will also roughen up the anti-aliasing of our other edges. Also if you're using opacity in these gradients then you will need to adjust those tableValues below to the range that you want (aka if your fill is 0.4 opacity, then your tableValues would look like "0 .1 .4 .4 .4"). If you have variable opacity in your gradients, then you can play around with other types of component transfers that will preserve the opacity gradients better.
<svg id="background-svg" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 150 75" >
<defs>
<linearGradient y2="1" x2="1" y1="0" x1="0" id="triangleGradient">
<stop stop-color="black" offset="0"/>
<stop stop-color="blue" offset="1"/>
</linearGradient>
<filter id="mynameisgrout">
<feComponentTransfer>
<feFuncA type="table" tableValues="0 .25 1 1 1"/>
</feComponentTransfer>
</filter>
</defs>
<g filter="url(#mynameisgrout)">
<polygon points="0,75 100,75 50,0" fill="url(#triangleGradient)"></polygon>
<polygon points="50,0 150,0 100,75" fill="url(#triangleGradient)"></polygon>
</g>
</svg>
The SVG shape rendering option allows to configure what's important for rendering.
In this case shape-rendering="crispEdges" solves the problem.
See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering

SVG Linear gradient doesn't work in Safari

I've got an SVG object that contains a linear gradient embedded directly in a document. It works fine in Chrome and Firefox, but in Safari nothing is rendered. If I create the SVG as a file and embed it using the Object tag, it works fine in Safari. Other shapes and fills work, it's just linear gradient that doesn't work. I guess I could use the object, but I'd prefer to embed the SVG directly.
I've create a demo here (works in Chrome, not Safari): http://jsfiddle.net/sjKbN/
I came across this answer which suggests setting the content type to application/xhtml+xml, but this in itself seems to cause other problems.
Just wondering if anyone had come across any other fixes or ideas to get this working.
Your gradient will work in Safari if you wrap a defs tag around it:
<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="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
<defs>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="5.6665" y1="149.5" x2="293.333" y2="149.5">
<stop offset="0" style="stop-color:#FFF33B"/>
<stop offset="0.0595" style="stop-color:#FFE029"/>
<stop offset="0.1303" style="stop-color:#FFD218"/>
<stop offset="0.2032" style="stop-color:#FEC90F"/>
<stop offset="0.2809" style="stop-color:#FDC70C"/>
<stop offset="0.6685" style="stop-color:#F3903F"/>
<stop offset="0.8876" style="stop-color:#ED683C"/>
<stop offset="1" style="stop-color:#E93E3A"/>
</linearGradient>
</defs>
<rect x="5.667" y="5.333" fill="url(#SVGID_1_)" width="287.667" height="288.333"/>
</svg>
​It seems that wrapping your references in defs is encouraged but not obligatory according to spec. So this is a bug in Safari.
About Alpha : It seems that Safari (7 at this moment) does not cover SVG color alpha channel, use stop opacity attribute. it works fine!
<stop stop-color="rgba(x,y,z,0.5)"> //safari does not work
<stop stop-color="rgb(x,y,z)" stop-opacity="0.5"> //ok
The accepted answer was not the solution for me.
My problem was the presence of a <base href="/" /> tag in my index file. Simply removing it solved the problem for me.
If you cannot remove it, probably some workaround already exist: found this gist but I did not tested it.
Update
Simply removing the href broke the child routing of my angular app, the proper workaround is to prepend to the linearGradient id with the page relative location. I wrapped the logic in a method like this:
get svgFill(): string {
return `url(${this.location.path()}#${this.gradientId}) white`;
}
The answer is simple, all id's (not only <linear gradient>) need to be UNIQUE for all SVG files.
I had some troubles too making an inline SVG with a linear gradient work. The designer had put a - in the id of the <linearGradient. The solution was as simple as removing it.
<linearGradient id="linear-gradient">
...
<path fill="url(#linear-gradient)" d="..."/>
with
<linearGradient id="lineargradient">
...
<path fill="url(#lineargradient)" d="..."/>