Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG use and gradients as fill

I've been trying to externalize my SVG icons to a file and referencing them with markup like <svg><use xlink:href="file.svg#icon" /></svg>. In theory this works really nicely, but different browsers have issues with rendering. All the browsers are able to render the svg correctly when referencing the symbol with <use> inside the file and opening the svg file's url directly.

In short, is there a cross-browser way to get SVG linearGradients working as fills for elements when referencing the symbols with <svg><use/></svg> in the markup?

I set up a plunker demonstrating the problem: http://plnkr.co/edit/feKvZ7?p=preview

Simplified, the markup is like the following:

<!DOCTYPE html>
    <html>
      <body>
        <h1>SVG sprite test</h1>
        <svg width="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
          <use xlink:href="icon.svg#icon" />
        </svg>
      </body>
    </html>

And the SVG file looks like this:

  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <linearGradient id="gradient">
          <stop offset="0" stop-color="black" />
          <stop offset="1" stop-color="white" />
        </linearGradient>
      </defs>
      <symbol id="icon" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="40" stroke="black" fill="url(#gradient)" />
      </symbol>
    
      <use id="iconuse" xlink:href="#icon" width="100" height="100" />
    
    </svg>

This is what it looks like in the different browsers: Different results of rendering linear gradients for symbols in different browser

like image 675
RJo Avatar asked May 29 '17 06:05

RJo


1 Answers

The symbol tag is used to hide the elements that are inside it. Elements inside the symbol are called using the <use> command by their unique indicator.
Therefore, it is better to use this method of calling individual elements rather than calling the whole symbol

In addition, elements when using <use> fall into the shadow DOM and using CSS in some cases becomes impossible
Therefore, it is better to delete all internal styles inside symbol and assign them directly to the use command

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="black" />
      <stop offset="1" stop-color="white" />
    </linearGradient>
  </defs>
  <symbol  id="icon"  viewBox="0 0 100 100"> 
    <circle id="circle" cx="50" cy="50" r="40"   />
     <rect id="rect" x="100" y="10" width="100" height="100" />
  </symbol>

  <use class="iconuse" xlink:href="#circle" width="100" height="100" fill="url(#gradient)" stroke="black" />
     <use class="iconuse" xlink:href="#rect" width="100" height="100" fill="url(#gradient)" />
</svg>
like image 79
Alexandr_TT Avatar answered Oct 21 '22 05:10

Alexandr_TT