emersonthis
emersonthis

Reputation: 33398

How to scale inline SVG uniformly with %

I'm trying to use SVG elements in a fluid context, using % units to set the size proportional to the container.

If you include an SVG design like an image it works just like an image:

<img class="img-svg" src="box.svg" />

You can use CSS to easily scale it proportionally with stuff like this:

.img-svg { width:100%; height: auto; }

BUT

If you use inline SVG, everything changes...

<svg class="inline-svg" preserveAspectRatio="xMidYMid meet" viewBox="...">
    ...
</svg>

This WON'T work:

.inline-svg { display:block; width:100%; height: auto; }

If you do this it will expand the SVG's box to 100% but all the elements inside it wills stay the same size. Here's a jsfiddle: http://jsfiddle.net/s_d_p/jA62R/

What's the right way to do this so that the contents inside the SVG scale up/down uniformly?

Note1: I'm looking for a CSS/SVG solution. Not a javascript hack.

NOte2: I found this but it relies on fixed px units.

Upvotes: 7

Views: 6563

Answers (2)

emersonthis
emersonthis

Reputation: 33398

I'm still getting my head around this, but here's the best I've come up with so far...

css

.svg {
    display: block;
    width:100%;
    height: auto;
}

svg

<svg preserveAspectRatio="xMidYMid meet" viewBox="...">
...
</svg>

The CSS needs to set the display to block because the default for SVG is inline (not sure why). Then you can scale it's boundary like a div.

The way you get the contained svg nodes to play nicely also is by using the preserveAspectRatio attribute. As Robert pointed out in a comment above, the preserveAspectRatio attribute doesn't work if you don't have a viewBox attribute as well.

It's worth reading more about preserveAspectRatio here because there a lot if different values which will determine how the scaled elements interact with the surrounding space if the dimensions are not the same. For example, if your SVG is a short wide rectangle and your container is a tall skinny rectangle, what should the browser do with the extra space to make it fit?

[Be careful! The browser defaults for preserveAspectRatio differ a lot!]

Upvotes: 4

Kheema Pandey
Kheema Pandey

Reputation: 10285

you can apply a svg transform to the contents of the SVG tag. or you can use the CSS3 transform method as well.

.svg {width:100%; display:block;
transform:scale(5); 
-webkit-transform:scale(5); 
-moz-transform:scale(5); 
-ms-transform:scale(5); 
-o-transform:scale(5);
}

<svg class="svg" preserveAspectRatio="xMidYMid meet" viewbox="0 0 102 102">
<g transform="scale(0.5)">
/*rest code will come inside this.*/
</g>
</svg>

Here is your working Demo. http://jsfiddle.net/jA62R/10/

Upvotes: 2

Related Questions