Scale Inline Svg Symbol Referenced with <Use>

Scale inline SVG symbol referenced with use

Unfortunately it is the dimensions of the <svg> element that appears in your <header> that is important. There is no way to inherit a viewBox from a child symbol reference.

You would need to copy the viewBox (width and height) from the symbol.

.Header-logo {    height: 5rem;}
.Header-logo2 { height: 8rem;}
<svg class="SpriteSheet" width="0" height="0">    <symbol id="icon-logo" viewBox="-12 -79.61 407.19 108.36">        <path id="logo-upperLeft" d="M0-67.61l83.66 0 0-10 -93.66 0 0 30.92 10 0Z" transform="translate(-2 -2)"></path>        <path id="logo-upperRight" d="M383.19-67.61l-83.66 0 0-10 93.66 0 0 30.92 -10 0Z" transform="translate(2 -2)"></path>        <path id="logo-lowerLeft" d="M0 16.75l83.66 0 0 10 -93.66 0 0-30.92 10 0Z" transform="translate(-2 2)"></path>        <path id="logo-lowerRight" d="M383.19 16.75l-83.66 0 0 10 93.66 0 0-30.92 -10 0Z" transform="translate(2 2)"></path>    </symbol></svg>

<header class="Header"> <h1 class="Header-headline"> <a href="/"> <svg class="Header-logo" viewBox="0 0 407.19 108.36"> <use xlink:href="#icon-logo"></use> </svg> </a> </h1></header>
<header class="Header"> <h1 class="Header-headline"> <a href="/"> <svg class="Header-logo2" viewBox="0 0 407.19 108.36"> <use xlink:href="#icon-logo"></use> </svg> </a> </h1></header>

Cannot Change SVG use icon size when linked to symbol

The <defs>is an svg element. It always goes inside the svg. I've made a few changes and now it works. Please run the code and take a look at what I've done.

#box1 {  height: 10rem;  width: 10rem;}
#twitter{display:none;}
<svg id="twitter">    <defs>      <symbol id="twitter-symbol"><title>twitter</title>          <path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" fill="#000">          </path>      </symbol>    </defs>  </svg>

<div id="box1"> <svg viewBox="0 0 19.19 15.95" width="24"> <use xlink:href="#twitter-symbol"/> </svg></div>

Inline SVG doesn't scale

I'm not sure I understand clearly what's the problem you're asking for help so I'll try to answer a maximum I saw in your snippet.

  • If you can't see the chart, I think it's more because of the default fill color being black, than because of the size. If you add fill: #FFF into your #wrapper's css or in an appropriate svg{} statement, you'll see it clearly.

  • If your compass is so small, I think it's because your drawn pathes only are 50px large in a 1024x1024 document. (You're setting a viewBox="0 0 1024 1024" to your <symbol> element but setting it to something like 0 0 50 50 will help if you want to use transformations later, or even better, redraw it in a document where they fit right).

  • You say that you want to animate those graphics. There are actually a lot of ways to do so. You can look to CSS animations (via a style sheet) or SMIL (directly in the inline svg) or via javascript (by modifying directly the attributes as noticed in Nicholas Kyriakides answer). Look at the examples in the snippet below.

var scale = 1;window.onload = function(){document.getElementById('p').addEventListener('click', function(){document.getElementById('linked').setAttribute('transform', 'scale('+(scale+=.1)+')');}, false);document.getElementById('m').addEventListener('click', function(){document.getElementById('linked').setAttribute('transform', 'scale('+(scale-=.1)+')');}, false);};
.icon { width: 400px; height: 200px; }.wrapper { background: black; width: 80%; max-width: 400px; margin: 0 auto; color:#fff; fill: #fff; }text { cursor: pointer; }.icon:hover{ cursor: pointer; }.icon:hover .chart{ fill: #FAF; -webkit-animation: color 5s; animation: color 5s forwards alternate; }@-webkit-keyframes color{   0%{ fill : #FFF;}  10%{ fill : #508694;}  50%{fill: #FBB03B;}  90%{ fill : #D19B6F;}  100%{ fill : #FFF;}  }@keyframes color{   0%{ fill : #FFF;}  10%{ fill : #508694;}  50%{fill: #FBB03B;}  90%{ fill : #D19B6F;}  100%{ fill : #FFF;}  }
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="chart" viewBox="0 0 1042 1024">  <path class="chart" d="M893.78 455.769h145.017v568.231h-145.017v-568.231z"  />  <path class="chart" d="M671.815 0h145.017v1024h-145.017v-1024z"  />  <path class="chart bar3" d="M446.89 624.462h145.017v396.578h-145.017v-396.578z"  />  <path class="chart" d="M224.925 227.884h145.017v796.116h-145.017v-796.116z"  />  <path class="chart" d="M0 71.029h145.017v952.971h-145.017v-952.971z"  /> </symbol> <symbol id="compass" viewBox="0 0 46.6 46.6">  <path class="compas__outer" fill="#FFFFFF" d="M22.7,0C10.2,0,0,10.2,0,22.7c0,12.5,10.2,22.7,22.7,22.7   c12.5,0,22.7-10.2,22.7-22.7C45.4,10.2,35.3,0,22.7,0L22.7,0z M22.7,42.9c-11.1,0-20.1-9-20.1-20.1c0-11.1,9-20.1,20.1-20.1   c11.1,0,20.1,9,20.1,20.1C42.9,33.8,33.8,42.9,22.7,42.9L22.7,42.9z M22.7,42.9"/>  <path class="compass__needle" fill="#FFFFFF" d="M24.7,20.7C24,20,23,19.7,22,19.9l1.5-1.5l-12-6.9l6.9,12l1.5-1.5   c-0.2,0.9,0,2,0.8,2.7c0.7,0.7,1.8,1,2.7,0.8L21.9,27l12,6.9l-6.9-12l-1.5,1.5C25.7,22.5,25.5,21.4,24.7,20.7L24.7,20.7z    M21.8,23.6c-0.5-0.5-0.5-1.3,0-1.8c0.5-0.5,1.3-0.5,1.8,0c0.5,0.5,0.5,1.3,0,1.8C23.1,24.1,22.3,24.1,21.8,23.6L21.8,23.6z    M31.9,31.9l-8.7-5.1l3.7-3.7L31.9,31.9z M31.9,31.9">   <animateTransform attributeName="transform" begin="0s" dur="2s" type="rotate" from="0 22.7 22.7" to="360 22.7 22.7" repeatCount="indefinite" />  </path> </symbol> <symbol id="linked-in" viewBox="0 0 1070 1024">  <path d="M241.778 1024v-689.778h-227.556v689.778h227.556zM128 238.222c78.222 0 128-53.333 128-120.889s-46.222-117.333-128-117.333c-78.222 0-128 49.778-128 120.889 0 64 49.778 117.333 128 117.333v0 0zM369.778 1024c0 0 3.556-625.778 0-689.778h227.556v99.556c28.444-46.222 85.333-117.333 209.778-117.333 149.333 0 263.111 99.556 263.111 309.333v394.667h-227.556v-366.222c0-92.444-32-156.444-117.333-156.444-64 0-99.556 42.667-117.333 85.333-7.111 14.222-7.111 35.556-7.111 56.889v384h-231.111z" fill="#FFF"/> </symbol></svg>
<div class="wrapper"> <h1>CSS @keyframe</h1> <svg role="img" class="icon" width="400" height="200"> <!-- I had to get it out of the <use> because webkit browsers #@ø‡~! http://codepen.io/AmeliaBR/pen/lshrp--> <g id="chart"> <path class="chart" d="M172.1,90.6H200V200h-27.9V90.6L172.1,90.6z"/> <path class="chart" d="M129.3,2.8h27.9V200h-27.9L129.3,2.8L129.3,2.8z"/> <path class="chart" d="M86,123.1H114v76.4H86V123.1L86,123.1z"/> <path class="chart" d="M43.3,46.7h27.9V200H43.3L43.3,46.7L43.3,46.7z"/> <path class="chart" d="M0,16.5h27.9V200H0C0,200,0,16.5,0,16.5z"/> </g> <use xlink:href="#chart" id="charts" x="100"></use> </svg> <h1>SMIL animateTransfrom</h1> <svg viewBox="0 0 1024 1024" preserveAspectRatio="xMidYMin slice" style="width: 100%; padding-bottom: 80%; height: 70px; overflow: visible"> <use xlink:href="#compass"></use> </svg> <h1>Javascript</h1> <svg viewBox="0 0 1024 1024"> <use xlink:href="#linked-in" id="linked"></use> <text id="p" font-size="200" y="140" x="650">+</text> <text id="m" font-size="200" y="140" fill="" x="800">-</text> </svg></div>

How can I make an svg scale with its parent container?

To specify the coordinates within the SVG image independently of the scaled size of the image, use the viewBox attribute on the SVG element to define what the bounding box of the image is in the coordinate system of the image, and use the width and height attributes to define what the width or height are with respect to the containing page.

For instance, if you have the following:

<svg>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

It will render as a 10px by 20px triangle:

10x20 triangle

Now, if you set only the width and height, that will change the size of the SVG element, but not scale the triangle:

<svg width=100 height=50>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

10x20 triangle

If you set the view box, that causes it to transform the image such that the given box (in the coordinate system of the image) is scaled up to fit within the given width and height (in the coordinate system of the page). For instance, to scale up the triangle to be 100px by 50px:

<svg width=100 height=50 viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

100x50 triangle

If you want to scale it up to the width of the HTML viewport:

<svg width="100%" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

300x150 triangle

Note that by default, the aspect ratio is preserved. So if you specify that the element should have a width of 100%, but a height of 50px, it will actually only scale up to the height of 50px (unless you have a very narrow window):

<svg width="100%" height="50px" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

100x50 triangle

If you actually want it to stretch horizontally, disable aspect ratio preservation with preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

300x50 triangle

(note that while in my examples I use syntax that works for HTML embedding, to include the examples as an image in StackOverflow I am instead embedding within another SVG, so I need to use valid XML syntax)

How to scale SVG when svg reference another

You need to correct the viewBox, its also wrong in the first SVG.

.row {  display: flex;  justify-content: space-between;  align-items: center;  border: solid 1px;}
svg.icon { border: solid 1px tomato; /**debug*/ overflow: visible;}
.icon use { border: solid 1px green;}
<svg style="display:none" viewBox="0 0 600 600" width="24" height="24"> <defs><g id="ico-and" >        <path  d="M152.682,458.363c0,15.3,10.2,25.5,25.5,25.5h25.5v89.25c0,20.4,17.85,38.25,38.25,38.25s38.25-17.85,38.25-38.25v-89.25    h51v89.25c0,20.4,17.85,38.25,38.25,38.25s38.25-17.85,38.25-38.25v-89.25h25.5c15.3,0,25.5-10.2,25.5-25.5v-255h-306V458.363z     M88.932,203.363c-20.4,0-38.25,17.851-38.25,38.25v178.5c0,20.4,17.85,38.25,38.25,38.25s38.25-17.85,38.25-38.25v-178.5    C127.182,221.213,109.332,203.363,88.932,203.363z M522.432,203.363c-20.4,0-38.25,17.851-38.25,38.25v178.5    c0,20.4,17.85,38.25,38.25,38.25s38.25-17.85,38.25-38.25v-178.5C560.682,221.213,542.832,203.363,522.432,203.363z     M394.932,55.463l33.15-33.15c5.1-5.1,5.1-12.75,0-17.85c-5.101-5.101-12.75-5.101-17.851,0l-38.25,38.25    c-17.85-12.75-40.8-17.851-66.3-17.851s-48.45,5.101-68.85,15.3l-35.7-38.25c-5.1-2.55-15.3-2.55-20.4,0    c-2.55,5.101-2.55,15.301,0,20.4l33.15,33.15c-35.7,28.05-61.2,71.399-61.2,122.399h306    C458.682,126.863,433.182,80.963,394.932,55.463z M254.682,126.863h-25.5v-25.5h25.5V126.863z M382.182,126.863h-25.5v-25.5h25.5    V126.863z" />      </g>          </defs></svg>
<div class="row"> <svg class="icon" alt="SO" viewBox="0 0 600 600" width="24" height="24"> <use xlink:href="#ico-and"></use> </svg> <p>System</p></div>

Dynamically resize inline SVG

If you inline SVGs you don't need Javascript. For example, you can scale to 48px a 24px icon like this:

<div class="Icon">
<svg class="Icon-image" width="24" height="24" viewBox="0 0 24 24">...</svg>
</div>

CSS:

.Icon {
width: 48px;
}
.Icon svg {
width: 100%;
height: auto;
}


Related Topics



Leave a reply



Submit