【问题标题】:How to apply linear gradient to SVG <symbol> in <use> tag?如何在 <use> 标签中对 SVG <symbol> 应用线性渐变?
【发布时间】:2022-01-02 10:04:55
【问题描述】:

我的 HTML 文件中有以下几行:

<div class="account-container">
 <svg id="icon-account" style="width: 5rem; height: 5rem;">
  <use href="/icons.svg#icon-account" />
 </svg>
</div>

icons.svg 看起来像这样:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>

  <linearGradient id="gradient1" x1="21.3635" y1="1.72727" x2="21.3639" y2="41"     gradientUnits="userSpaceOnUse">
   <stop stop-color="#7DC2C9"/>
   <stop offset="1" stop-color="#446B73"/>
  </linearGradient>

  <symbol id="icon-account" viewBox="0 0 42 42" >
   <path d="M6.09091 34.3314C10.9277 29.4164 15.2241 27.245 21 27.1818C27.3352 27.4877 31.7332 29.4904 36.2727 33.9136M41 21C41 32.0457 32.0457 41 21 41C9.95431 41 1 32.0457 1 21C1 9.95431 9.95431 1 21 1C32.0457 1 41 9.95431 41 21ZM26.4545 15.1818C26.4545 18.1943 24.0125 20.6364 21 20.6364C17.9875 20.6364 15.5455 18.1943 15.5455 15.1818C15.5455 12.1694 17.9875 9.72727 21 9.72727C24.0125 9.72727 26.4545 12.1694 26.4545 15.1818Z" fill="none"/>
  </symbol>

 </defs>
</svg>

我想对图标应用#gradient1。在 SVG 文件的路径上或在 CSS 中使用 stroke=url(#gradient1) 设置描边不起作用,并且根本不会渲染图标。

在 HTML 文档中包含以下 SVG defs 允许引用渐变,然后它就可以工作了:

<svg
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
  <defs>
    <linearGradient
      id="gradient1"
      x1="21.3635"
      y1="1.72727"
      x2="21.3639"
      y2="41"
      gradientUnits="userSpaceOnUse"
    >
      <stop stop-color="#7DC2C9" />
      <stop offset="1" stop-color="#446B73" />
    </linearGradient>
  </defs>
</svg>

但是,我想避免使用 SVG 定义污染 HTML,并将所有 SVG 相关代码保存在单独的 icons.svg 文件中。

如何将渐变应用到此图标?

谢谢!

【问题讨论】:

    标签: css svg linear-gradients


    【解决方案1】:

    看起来像一个 Chrome 错误,可能是 2012 年臭名昭著的 Issue 109212: SVG (filter | fill […]) from external files not applied;在相关question: Gradient in defs not showing up in SVG sprite in Chrome找到。

    <svg style="width: 5rem; height: 5rem;">
     <use href='data:image/svg+xml,<svg version="1.1" 
      xmlns="http://www.w3.org/2000/svg">
      <defs>
       <linearGradient id="gr">
        <stop offset=".2" stop-color="red" />
        <stop offset=".8" stop-color="blue" />
       </linearGradient>
       <symbol id="icon" viewBox="0 0 8 8" >
        <path d="M0 0 L 8,0 8,8 0,8 Z M 2,2 L 6,2 6,6 2,6 Z" 
         fill="url(%23gr)"
         stroke="gold" />
       </symbol>
      </defs>
     </svg>#icon' />
    </svg>

    此示例代码使用 dataURI 来模拟外部资源。在 Firefox 中,它可以正确渲染金色描边和红蓝渐变填充,但在 Chrome 中,只有描边可见。


    对于同一个 SVG,直接在 HTML 中放置 defs 的相同 SVG 可以在两种浏览器中使用:

    <svg style="width: 5rem; height: 5rem;">
     <use href='#icon' />
    </svg>
    
    <svg version="1.1" 
      xmlns="http://www.w3.org/2000/svg">
      <defs>
       <linearGradient id="gr">
        <stop offset=".2" stop-color="red" />
        <stop offset=".8" stop-color="blue" />
       </linearGradient>
       <symbol id="icon" viewBox="0 0 8 8" >
        <path d="M0 0 L 8,0 8,8 0,8 Z M 2,2 L 6,2 6,6 2,6 Z" 
         fill="url(#gr)"
         stroke="gold" />
       </symbol>
      </defs>
     </svg>

    并且将自包含的 SVG 加载到图像中,证明在同一个真正的 SVG(不是 SVG-in-HTML)中的引用在两种浏览器中都有效。

    <img src="data:image/svg+xml;charset=utf-8,
    <svg xmlns='http://www.w3.org/2000/svg' version='1.1'>
     <defs>
      <linearGradient id='gr'>
       <stop offset='.2' stop-color='red'/>
       <stop offset='.8' stop-color='blue'/>
      </linearGradient>
      <symbol id='icon' viewBox='0 0 8 8'>
       <path d='M0 0 L 8,0 8,8 0,8 Z M 2,2 L 6,2 6,6 2,6 Z'
        fill='url(%23gr)'
        stroke='gold'/>
      </symbol>
     </defs>
     <use href='%23icon'/>
    </svg>"></img>

    【讨论】:

    • 有用的答案(+)
    猜你喜欢
    • 2018-05-14
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多