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 use jQuery to check if element breaks to the next line?

    How to Write an Angular directive to update CSS class based on form validation

    How to add multiple attributes in CSS in input element [duplicate]

    How to break text in a line in a div by css?

    How to to make a gap between rows in FlowPanel in Css in Gwt?

    How can I make this HTML5 canvas progress bar fill from the bottom up instead of the top down?

    How to use pure CSS to control other elements under same parent?

    How do you replicate this box-shadow effect?

    How determine css text of each node in html

    How to get inputs in the same line with css?

    how to set the child-class height as per the parent div using css

    How to modify wordpress plugin css [closed]

    DevTools: How to visualize scss changes automatically without the need to save

    How to change active tab to first css

    How do i change the styling of a nodes CSS through javascript(d3)

    How to make the page to fit screen width on mobile device?

    How to make styling and functioning of form elements get not to break in all browsers?

    How to use display:flex in CSS to create a mix of fixed with and dynamic proportional width columns?

    How to make a background color stretch to left and right of viewport in Safari Browsers

    CSS - How to center an image without class or id?

    How do I make link the highlight link conform to CSS shape

    how to change css for flip animation on button click?

    How to get minimal jQuery slideshow to slide properly?

    How to edit .css file from html via jquery

    How to add border for html tr

    How to center an unordered list?

    how to let CMS make use of my css files instead of its own css?

    Border-bottom not showing correctly

    How to make a list float to the right in CSS?

    JS+CSS How to display images from an array from top right to bottom left