Reputation: 1519
I'm very confused about the <svg>
spec as it relates to the <use>
tag because everything I've read about it online seems to implement the tag with subtle differences.
On css-tricks the <svg>
is added with a viewBox
in the <symbol>
:
<svg style="display: none;">
<defs>
<symbol id="basketball" viewBox="0 0 100 100">
<title>Basketball</title>
<path d="M28.1,3 ... "/>
</symbol>
</defs>
</svg>
and then the <symbol>
is plainly referenced just with the id
:
<svg class="icon-basketball">
<use xlink:href="#basketball"></use>
</svg>
The same is true for this article and even more so in this article by Chris Coyier, where he explicitly points out that <symbol>
is a better tag because you don't need a viewBox
when referencing it.
However, referencing a symbol with a viewBox
does not work for me, and I end up with the same error as in this SO question, which concludes that you do, in fact, need the viewBox
when referencing a <symbol>
. This article even proposes a hack for dealing with 'intrinsic svg sizing'.
Indeed, in this short jsfiddle/snippet, you can see that with a single <symbol>
, if I add the viewbox into the <svg>
reference it is sized correctly, without any whitespace. Yet, with the viewbox removed, there are large 'margins' at the top and bottom.
<link href="https://unpkg.com/[email protected]/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>
So what am I getting wrong about <use>
is it the way I am defining the <symbol>
, which currently is being generated through svg-sprite on webpack. Or has there been a recent change in the way <svg>
s are externally referenced?
Thanks!
Upvotes: 3
Views: 294
Reputation: 14545
In the article you refer to, Chris Coyier used symbol
to store icons in the sprite.
Each symbol
in the sprite can have its ownviewBox
, with individual parameter values, which allows you to additionally scale and position each icon individually.
<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>
In your case, when using the <use>
, as Robert Longson wrote:
in one instance it has size information, in the other it does not.
In the nested svg, there is also an additional scaling.
Therefore, if you want both clones to be the same size, add a svg viewBox
to the second instance with the same parameters viewBox =" 0 0 24 24 "
<link href="https://unpkg.com/[email protected]/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>
Upvotes: 3