Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I reference an SVG linear gradient defined in an external file (paint server)?

Please have a look at this Pen:

http://codepen.io/troywarr/pen/VYmbaa

What I'm doing here is:

  • defining an SVG symbol (<symbol>)
  • defining an SVG linear gradient (<linearGradient>)
  • using the <use> element to reference the SVG symbol I've created
  • in the CSS, defining two classes:
    • external, which references the linear gradient defined in this external .svg file (right click and view source)
    • internal, which references the linear gradient defined in the local HTML (which is, I believe, effectively identical to the one in the external file)

Because I've applied the internal class to the <svg> element at the bottom of the HTML example, the gradient is applied, rendering a blue gradient checkmark. That's what I'm after.

But, if you switch the internal class to external in the HTML example, the checkmark is no longer visible:

http://codepen.io/troywarr/pen/vEymKX

When I watch Chrome Inspector's "Network" tab, I don't see the browser trying to load the SVG file at all. Is there a problem with my syntax, or is something else going on here?

It at least looks like I'm doing this right, based on a few references I've found:

  • http://www.w3.org/TR/SVG/painting.html#SpecifyingPaint
  • http://www.w3.org/TR/SVG/linking.html#IRIReference
  • https://stackoverflow.com/a/7118142/167911

But, nothing I've tried so far has allowed me to reference a linear gradient defined in an external .svg file.

Thanks for any help!

like image 688
Bungle Avatar asked Jan 03 '15 06:01

Bungle


2 Answers

After more research, it looks like this is a browser support issue. See:

  • https://code.google.com/p/chromium/issues/detail?id=109212
  • https://bugs.webkit.org/show_bug.cgi?id=105904

Sadly, I'd come across this question before posting mine, and had thought that surely, in 5-1/2 years, browser support would have caught up - but that doesn't appear to be the case.

As of 2015, apparently Firefox and Opera are the only two browsers to support this in any substantial way.

Back to the drawing board...

like image 50
Bungle Avatar answered Sep 21 '22 08:09

Bungle


You can use svg4everybody with polyfill: true option, it will insert all external symbols instead of use tags. But it will cause the second svg loading.

So you can download svg using an ajax request and then insert it on the page hiding with the styles.

<script>var ajax=new XMLHttpRequest;ajax.open("GET","/img/svg-sprite.svg",!0),ajax.send(),ajax.onload=function(a){var b=document.createElement("div");b.classList.add("hidden"),b.innerHTML=ajax.responseText,document.body.insertBefore(b,document.body.childNodes[0])};</script>

In this case:

/img/svg-sprite.svg — is your svg path.

.hidden class styles:

.hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
}

And your code might look like this:

<svg><use xlink:href="#logo"></use></svg>
like image 45
mcmimik Avatar answered Sep 19 '22 08:09

mcmimik