Home > Net >  Why do colons in linearGradient IDs break them when the SVG is used in an <img> tag?
Why do colons in linearGradient IDs break them when the SVG is used in an <img> tag?

Time:11-12

Take the following source and save it as a test.svg file.

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="myGradient:1234" gradientTransform="rotate(90)">
      <stop offset="5%" stop-color="gold"></stop>
      <stop offset="95%" stop-color="red"></stop>
    </linearGradient>
  </defs>

  <circle cx="5" cy="5" r="4" fill="url('#myGradient:1234')"></circle>
</svg>

Open the test.svg file in Chrome and you'll see a circle which blends from yellow to red. However, if you create an HTML file and include this SVG in the form of <img src="text.svg" /> you'll see that, at least in Chrome, no color is applied to the circle.

If you update test.svg to change the ID from myGradient:1234 to myGradient then the color will start working when the image is used in an <img> tag.

Why is this behavior different?

CodePudding user response:

Actually ID's containing ':'(colon) shouldn't work in a self contained file either. It's a matter of XML naming compliance.

An excerpt from the MDN Docs

It must be valid in XML documents. A stand-alone SVG document uses XML 1.0 syntax, which specifies that valid IDs only include designated characters (letters, digits, and a few punctuation marks), and do not start with a digit, a full stop (.) character, or a hyphen-minus (-) character.

As a rule of thumb:
apply the same naming rules, you would also need for html/css/js selectors:

  1. keep it ansi: avoid non-english characters like diacritics/accents etc.
  2. don't start selector names with any numbers – appending them like 'element-01' is perfectly OK
  3. avoid characters, which are also used as operators: like the colon for pseudo-elements, plus or tilde for adjacent siblings etc.

#myGradient\:1234{
color:red
}

#myGradient\:1234,
#\31 234myGradient{
color:#000
}

#myGradient-1234{
color:green
}
<ul>
<li id="myGradient-1234">Selectable!</li>
<li id="myGradient:1234">Not selectable: selector contains <strong>colon operator reserved for pseudo elements</strong>. You might however escape the colon by a backslash</li>
<li id="1234myGradient">Not Selectable: selector starts with <strong>numbers</strong></li>
</ul>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related