将 <svg> 资源放在 </body> 之后是否合法?

Is it legal to put <svg> resources after </body>?

可不可以把svg资源used放在网站body后面,以便保留 他们之外的东西会被渲染?

简而言之:以下行为是否合法?

<!DOCTYPE html>
<html>
  <head>...</head>
  <body>
    <svg xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns="http://www.w3.org/2000/svg"
         viewBox="0 0 315.424 315.424" >
      <use href="#arrow" fill="rgb(0,44,89)" />
    </svg>
  </body>
  <svg>
    <g id="arrow">
      <path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886
         c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19
         c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375
         S314.142,223.815,311.929,222.266z" />
    </g>
  </svg>
</html>

如果目的不是要在文档中呈现原始 #arrow,您可以将其包含在 body 中的 svg 内,包围 defs .

下面截图中的演示。

<svg xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   viewBox="0 0 315.424 315.424">
   <defs>
      <g id="arrow">
         <path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886
            c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19
            c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375
            S314.142,223.815,311.929,222.266z" />
      </g>
   </defs>
   <use href="#arrow" fill="rgb(0,44,89)" />
</svg>

如前评论所述:
它无效,许多浏览器不会显示您的元素。
因此,在 <body> 的顶部或底部插入 svg 资源是更可取的方法。

注意: 通过 display:none 隐藏您的资产 svg 会破坏一些引用的定义,例如:

  • 过滤器
  • 渐变
  • 面具和clip-paths

它对形状元素(如图标)完美无缺

例子

function displayNone() {
  document.querySelector('#svgAssets').style.display = 'none';
}
svg {
  border: 1px dotted #ccc;
  height: 10em;
  display: inline-block;
}
<p><button onclick="displayNone()">Set display:none</button></p>
<svg viewBox="0 0 315.424 315.424">
  <use href="#arrow" fill="red" />
</svg>
<svg viewBox="0 0 100 100">
  <use href="#circle" fill="green" />
</svg>
<svg viewBox="0 0 200 100">
  <use href="#ellipse" fill="url(#gradient)" />
</svg>

<svg id="svgAssets" style="visibility:visible; width:0; height:0" aria-hidden="true">
  <defs>
      <linearGradient id="gradient">
        <stop stop-color="red" offset="0%"/>
        <stop stop-color="orange" offset="100%"/>
      </linearGradient>
  </defs>
  <symbol id="arrow" viewBox="0 0 315.424 315.424">
    <path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886 c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19 c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375 S314.142,223.815,311.929,222.266z" />
  </symbol>
  <symbol id="circle" viewBox="0 0 100 100">
    <circle cx="50%" cy="50%" r=50% />
  </symbol>
  <symbol id="ellipse" viewBox="0 0 200 100">
    <ellipse cx="100" cy="50" rx="100" ry="50" />
  </symbol>
</svg>

在上面的示例中,我使用了 <symbol> 元素,它可以用作 <defs> 的替代项。它们还支持每个图标的不同 viewBox 属性。

如果您只需要通过 <use> 放置图标,您也可以像这样使用外部文件引用:

<svg viewBox="0 0 315.424 315.424">
  <use href="svgIcons.svg#arrow" fill="red" />
</svg>

但是,您的 svg 文件必须是同一个域(或使用适当的 CORS headers 发送)