Cet article est également disponible en français

For an image format that features infinite scalability, 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;">
SVG illustration of a happy monkey face

While this works in many cases, sometimes it isn’t enough, especially if you’re trying to embed the SVG illustration via an <object> tag or 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. 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:

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; 
}
Responsive SVG illustration of Japanese shoto calligraphy inside a container

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>

Note that all content inside the SVG will scale, including text.

In SVG articles to come, I’ll explain just what the viewBox attribute is for, together with providing fallbacks for browsers that lack support for SVG.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.