For an image format that features infinite scalability, SVG can be a surprisingly difficult format to make responsive: vector images do not adjust themselves to the size of the viewport by default.
Make A Responsive SVG Image
As an image, you can make a SVG vector illustration scale with the page content as you would any other:
<img src="monkey.svg" alt="Monkey face" style="width: 100%; height: auto;">
While this works in many cases, sometimes it isn’t enough, especially if you’re trying to embed the SVG illustration by entering the code directly into the page. In that case, simply modifying the width
and height
of the element won’t work.
Making Inline SVG Responsive
After being pasted into the <body>
of an HTML document, embedded SVG code will typically look something like this:
<body>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500"
enable-background="new 0 0 500 500" xml:space="preserve">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10"
cx="250" cy="250" r="200" opacity="0.6" />
</svg>
</body>
With the <svg>
root element cleaned up, the code is much more presentable:
<svg version="1.1" viewBox="0 0 500 500">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10"
cx="250" cy="250" r="200" opacity="0.6" />
</svg>
Removing most of the redundant <svg>
element attributes makes the illustration responsive, but at the cost of adding space above and below the vector image in some browsers (IE in particular). You might assume that the remaining viewBox
attribute is the culprit, but it’s not: leave that alone. We have to take three more steps to integrate the responsive SVG element with our page content to make it work in all browsers.
First, surround the SVG code with a <div>
and add a preserveAspectRatio
attribute and class to the <svg>
root element:
<div class="svg-container">
<svg version="1.1" viewBox="0 0 500 500"
preserveAspectRatio="xMinYMin meet" class="svg-content">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10"
stroke-miterlimit="10" cx="250" cy="250" r="200" opacity="0.6" />
</svg>
</div>
That moves the SVG illustration to the top of its display container. To complete the presentation, we use a variation of the old absolutely-positioned-element-inside-a-relative-container trick, with an offset padding, rather like the approach used to make responsive video:
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: middle;
overflow: hidden;
}
Note that the width
used in the CSS assumes that you want the SVG image to be the full width of the page (or at least its parent container). The padding-bottom
amount represents a ratio between the SVG illustration’s height and width. Dividing the height
of the document’s viewBox
by its width
gives a 1:1 ratio in this case, meaning padding-bottom
should be set to 100%
. If the SVG image was wider than it was tall, say 1:2, the padding-bottom
would be set to 50%
.
Finally, position the SVG inside the container with a little more CSS:
.svg-content {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
This provides a solution in which the SVG illustration can scale gracefully on the page without disturbing other content; the same code will work on an <object>
tag used to embed the vector drawing:
<div class="svg-container">
<object type="image/svg+xml" data="samurai.svg"
width="100%" height="100%" class="svg-content">
</object>
</div>
Further Resources
Sara Soueidan also has an excellent article on making SVG responsive.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.