Search code examples
htmlsvghtml-head

Don't render SVG element with definitions only


I'd like to have one <svg> tag in my page that includes all my SVG definitions that I'll be using on other SVG elements.
Something like this:

<html>
<head>

<svg>
    <defs>
        <filter id="shadow1">
            <feDropShadow dx="3" dy="7" stdDeviation="2"/>
        </filter>
    </defs>
</svg>

</head>
<body style="display: flex">

    <svg viewBox="0 0 100 100" width="100">
        <path d="M0,0 L50,50" stroke="red" filter="url(#shadow1)" />
    </svg>

</body>
</html>

This works, but the problem is that the browser renders the <svg> tag that's in the <head> as if it was inside the body.

If I set width=0 and height=0 on the <svg> tag, it disappears but it's still a child element of the <body>.

Is it possible to have an <svg> tag with definitions only but outside the page's <body>?

Or a least some way of telling the browser that the <svg> element is purely declaratory and not meant to be part of the visible area of the document.

P.S.: I don't want to use and external .svg file because the definitions inside are dynamic and depend on the page being viewed.


Solution

  • No, SVGElement (<svg>) is not part of the meta-data contents, only content-type allowed in <head>. It must be a descendant of the <body>.

    But you can place it absolutely with CSS, set its z-index to -1, set its size attributes to 0 and it would not be rendered.

    svg.defs {
      position: absolute;
      z-index: -1;
    }
    <svg width="0" height="0" class="defs">
      <defs>
        <filter id="shadow1">
          <feDropShadow dx="3" dy="7" stdDeviation="2"/>
        </filter>
      </defs>
    </svg>
    <svg viewBox="0 0 100 100" width="100">
      <path d="M0,0 L50,50" stroke="red" filter="url(#shadow1)" />
    </svg>