什么是使用svg的正确方式?

3
我对<svg>规范与<use>标签的关系非常困惑,因为我在网上阅读的所有内容似乎都是使用微妙的不同之处实现该标签。
css-tricks上,<svg><symbol>中添加了viewBox
<svg style="display: none;">
  <defs>
    <symbol id="basketball" viewBox="0 0 100 100">
      <title>Basketball</title>
      <path d="M28.1,3 ... "/>
    </symbol>
  </defs>
</svg> 

然后<symbol>标签只需使用id进行引用:

<svg class="icon-basketball">
  <use xlink:href="#basketball"></use>
</svg>

同样适用于这篇文章,更是在Chris Coyier的这篇文章中明确指出,<symbol>标签更好,因为在引用它时不需要viewBox
然而,对我来说,使用带有viewBox的符号并不能正常工作,我最终遇到了与这个SO问题相同的错误,结论是在引用<symbol>时确实需要viewBox。甚至这篇文章提出了一种处理“内在SVG大小”的方法。
确实,在这个简短的jsfiddle/snippet中,你可以看到只需一个<symbol>,如果我将viewbox添加到<svg>引用中,则其大小会正确调整,没有任何空白。然而,如果删除viewbox,则顶部和底部会有大的“边距”。

<link href="https://unpkg.com/tachyons@4.9.0/css/tachyons.min.css" rel="stylesheet"/>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><symbol viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-zap" id="zap"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></symbol></defs></svg>

<div class="tc">


 <!-- svg is always oversized -->
 <svg class="outline w3 bg-red">
  <use xlink:href="#zap"></use>
 </svg>
 
 <!-- svg is the correct size -->
 <svg class="outline w3 bg-green"  viewBox="0 0 24 24">
  <use class="black" xlink:href="#zap"></use>
 </svg>
 

  
</div>

那么关于<use>,我哪里做错了?是我定义<symbol>的方式有问题吗?目前这个符号是通过webpack上的svg-sprite生成的。还是说最近<svg>外部引用的方式发生了变化?谢谢!

你想用JS操作SVG吗?否则,你可以在img标签中加载它,并使用CSS设置尺寸。 - Luckyfella
1
在这两种情况下使用方式相同,但包含<use>的<svg>元素不同,其中一个具有大小信息,而另一个则没有。 - Robert Longson
1个回答

3
在你提到的文章中,Chris Coyier使用symbol将图标存储在精灵中。
精灵中的每个symbol都可以有自己的viewBox,具有独立的参数值,这使得您可以额外缩放和单独定位每个图标。
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">

  <symbol id="beaker" viewBox="214.7 0 182.6 792">
    <!-- <path>s and whatever other shapes in here -->  
  </symbol>

  <symbol id="shape-icon-2" viewBox="0 26 100 48">
    <!-- <path>s and whatever other shapes in here -->  
  </symbol>

</svg>          

在你的情况下,使用 <use> 时,正如 Robert Longson 所写:

在一个实例中它有尺寸信息,在另一个实例中没有。

在嵌套 svg 中,还有额外的缩放比例。因此,如果你想让这两个克隆体大小相同,在第二个实例中添加一个 svg 的 viewBox,并使用相同的参数 viewBox =" 0 0 24 24 "

<link href="https://unpkg.com/tachyons@4.9.0/css/tachyons.min.css" rel="stylesheet"/>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><symbol viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-zap" id="zap"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></symbol></defs></svg>

<div class="tc">


 <!-- svg is the correct size -->
 <svg class="outline w3 bg-red" viewBox="0 0 24 24">
  <use xlink:href="#zap"></use>
 </svg>
 
 <!-- svg is the correct size -->
 <svg class="outline w3 bg-green"  viewBox="0 0 24 24">
  <use class="black" xlink:href="#zap"></use>
 </svg>
 

  
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接