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


Tags: html,css,html5,svg,scaling

Problem :

I want to have an inline svg element's contents scale when size is non-native. Of course I could have it as a separate file and scale it like that.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

However, I want to add additional styles to the SVG thru CSS, so linking an external one is not an option. How do I make an inline SVG scale?



Solution :

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)


    CSS Howto..

    How to get CSS to work only on specific WordPress pages?

    How to create 3d ribbon box in css

    How to make a table with no cells-per-row defined only with CSS

    How can I apply a style to a div using CSS as long as that div does NOT contain an element with a certain id?

    Yahoo news CSS, how to achieve behavior

    I have a link icon next to each link. How do I exclude the link icon from images?

    How to put Facebook and Twitter buttons next to each other?

    CSS - How to overlap elements over everything but each other? (No margin/padding etc)

    How to change the style of the arrow in a select box using css

    How to make this CSS compatible with IE browsers? [closed]

    How do I switch my CSS stylesheet using jQuery?

    How to edit .css file from html via jquery

    How to set a minimum content size of a webpage in html, css? [closed]

    How to align social media icons in one row?

    CSS newbie: How to align my link to the right side of the page?

    How to make a floating page div responsive

    How to fix too long css dropdown in Foundation 4 top bar?

    CSS: How can I hide a class which has no other class or ID?

    How to align both these elements in same line?

    How do you specify a css property to be applied only if the browser is IE in the stylesheet?

    How to add tooltip to image on hover with CSS

    Show background image out of the div [closed]

    How to change text color for link in tr element with CSS

    How to adjust the position a table to the bottom inside a DIV?

    how to make a double hover effect with css

    How to fetch the background of DIV on a bottom layer with exact position using jQuery and CSS

    img not showing in Safari in attempt to make img map responsive

    How to create a CSS Animation that is responding to horizontal mouse movement? [closed]

    CSS How to align checkbox image

    How to make div css background hover