Terry
Terry

Reputation: 66133

IE10 and 11 quirk on SVG use and linearGradients

I am creating an SVG sprite so that it can be reused multiple times throughout the site. In order to use the sprite, I am simply using <use> so that the symbol will be embedded in shadow DOM:

<!-- Icon -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
      <linearGradient id="grad1" x1="0" x2="0" y1="1" y2="0">
        <stop stop-color="steelblue" stop-opacity="1" offset="0%" />
        <stop stop-color="steelblue" stop-opacity="0" offset="100%" />
      </linearGradient>
    </defs>
  <use xlink:href="#svg-icon-grad" />
</svg>

<!-- Sprite -->
<svg style="display: none">
  <symbol id="svg-icon-grad" viewBox="0 0 250 100">
    <rect fill="url(#grad1)" x="0" y="0" width="100" height="100" />
  </symbol>
</svg>

The issue is that when I attempt to use a <linearGradient> as the fill attribute, it breaks in IE10 and 11. Strangely enough, it works perfectly fine in IE9, Chrome, Firefox, Safari, and Opera.

I know that if I avoid using <use> and instead embed the contents of the <symbol> directly, the linear gradient will work in IE10 and 11. However, I will want to avoid this since I prefer the sprites be stored in a separate file for easy maintenance.

Here is the code snippet:

svg {
  display: block;
  width: 250px;
  height: 100px;
}
<!-- Icon with fill -->
This is an icon with a fill, works in all browsers
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <use xlink:href="#svg-icon-fill" />
</svg>

<hr />

<!-- Icon with linear gradient -->
This is an icon with linear gradient, works in all browsers but breaks in IE10 and IE11 only (works in IE9)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
      <linearGradient id="grad1" x1="0" x2="0" y1="1" y2="0">
        <stop stop-color="steelblue" stop-opacity="1" offset="0%" />
        <stop stop-color="steelblue" stop-opacity="0" offset="100%" />
      </linearGradient>
      <linearGradient id="grad2" x1="0" x2="0" y1="1" y2="0">
        <stop stop-color="red" stop-opacity="1" offset="0%" />
        <stop stop-color="red" stop-opacity="0" offset="100%" />
      </linearGradient>
    </defs>
  <use xlink:href="#svg-icon-grad" />
</svg>

<!-- Sprite -->
<svg style="display: none">
  <symbol id="svg-icon-fill" viewBox="0 0 250 100">
    <rect fill="steelblue" x="0" y="0" width="100" height="100" />
    <circle fill="red" cx="200" cy="50" r="50" />
  </symbol>
  <symbol id="svg-icon-grad" viewBox="0 0 250 100">
    <rect fill="url(#grad1)" x="0" y="0" width="100" height="100" />
    <circle fill="url(#grad2)" cx="200" cy="50" r="50" />
  </symbol>
</svg>

As attached is the screenshot in various browsers:

IE9 (works):

IE9

IE10 (broken):

IE10

IE11 (broken):

IE11

Chrome (works):

Google Chrome

Firefox (works):

Mozilla Firefox

Safari (works):

OS X Safari

Upvotes: 0

Views: 185

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101830

Instead of display: none to hide the "sprite", use width="0" and height="0".

svg {
  display: block;
  width: 250px;
  height: 100px;
}
<!-- Icon with fill -->
This is an icon with a fill, works in all browsers
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <use xlink:href="#svg-icon-fill" />
</svg>

<hr />

<!-- Icon with linear gradient -->
This is an icon with linear gradient, works in all browsers but breaks in IE10 and IE11 only (works in IE9)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
      <linearGradient id="grad1" x1="0" x2="0" y1="1" y2="0">
        <stop stop-color="steelblue" stop-opacity="1" offset="0%" />
        <stop stop-color="steelblue" stop-opacity="0" offset="100%" />
      </linearGradient>
      <linearGradient id="grad2" x1="0" x2="0" y1="1" y2="0">
        <stop stop-color="red" stop-opacity="1" offset="0%" />
        <stop stop-color="red" stop-opacity="0" offset="100%" />
      </linearGradient>
    </defs>
  <use xlink:href="#svg-icon-grad" />
</svg>

<!-- Sprite -->
<svg style="width:0; height:0; visibility:hidden;">
  <symbol id="svg-icon-fill" viewBox="0 0 250 100">
    <rect fill="steelblue" x="0" y="0" width="100" height="100" />
    <circle fill="red" cx="200" cy="50" r="50" />
  </symbol>
  <symbol id="svg-icon-grad" viewBox="0 0 250 100">
    <rect fill="url(#grad1)" x="0" y="0" width="100" height="100" />
    <circle fill="url(#grad2)" cx="200" cy="50" r="50" />
  </symbol>
</svg>

Upvotes: 1

Related Questions