Responsive SVG: how to make an SVG scale
An SVG is responsive when it has a viewBox and CSS sets its size. The code for inline SVG, img tags and backgrounds, and logos that change with their width.
Published
To make an SVG responsive, give it a viewBox and let CSS decide its size: width: 100%; height: auto. The viewBox holds the drawing’s proportions, so the browser can work out the height for any width and scale the shapes to fit. An inline SVG with a fixed width and height and no viewBox cannot scale: making its box smaller only crops the drawing. The sizes quoted below were measured in Chrome.
Inline SVG
This example is for pasting into an HTML page:
<svg viewBox="0 0 400 300" style="width: 100%; height: auto">
<rect width="400" height="300" fill="gold"/>
<circle cx="200" cy="150" r="100" fill="teal"/>
</svg>
In a container 200 pixels wide, the SVG is 200 by 150. In one 900 pixels wide it is 900 by 675. The circle stays round and stays in the middle.
Three variations cover most layouts:
| Wanted | CSS on the <svg> |
|---|---|
| Fill the container’s width | width: 100%; height: auto |
| Fill it, but never exceed 600 pixels | width: 100%; max-width: 600px; height: auto |
Keep the size in the width and height attributes, and shrink only when the container is narrower | max-width: 100%; height: auto |
An inline <svg> that has a viewBox and no width or height attributes fills the container’s width with no CSS at all. Writing the CSS anyway makes the intention clear and protects against the cases under “Common problems”.
height: auto matters. If the tag has height="300" and CSS only sets width: 100%, the box becomes 200 by 300 in that narrow container, and the drawing sits in the middle of it with empty bands above and below.
SVG in an img tag
<img src="diagram.svg" alt="How the parts fit together" style="max-width: 100%; height: auto">
The same rule that makes photographs responsive works for an SVG file. What the file contains decides the starting size:
| The file’s root element has | With no CSS | With max-width: 100%; height: auto |
|---|---|---|
width, height and viewBox | Its own size, and it overflows a narrow container | Its own size, shrinking to fit |
viewBox only | The full width of the container, however wide | The same |
width and height only | Its own size | Shrinks to fit. The picture is scaled as a whole |
The first row is the best behaved: the image has a natural size, never grows past it, and shrinks when it must. Add width and height attributes to the <img> too, so the browser can reserve the space before the file arrives.
SVG as a CSS background
A background has no size of its own in the layout, so the element is sized first and the SVG is fitted to it with background-size.
| Value | Result |
|---|---|
contain | The whole drawing fits inside the element |
cover | The element is covered and the overflow is cropped |
100% 100% | The frame fills the element. The drawing is only distorted if the file has preserveAspectRatio="none" or has no viewBox |
SVG as a CSS background image goes through these.
Fixed height, flexible width
A banner or divider often needs the full width at a fixed height. Then the box no longer matches the viewBox, and preserveAspectRatio decides what gives. This is for pasting into HTML:
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" style="width: 100%; height: 120px">
<rect width="400" height="300" fill="gold"/>
<circle cx="200" cy="150" r="100" fill="teal"/>
</svg>
| preserveAspectRatio | In a box 800 wide and 120 tall |
|---|---|
| Left out | The drawing is fitted inside: 160 by 120, centred, with empty space either side |
xMidYMid slice | The drawing covers the box. The top and bottom are cropped |
none | The drawing is stretched to the box. The circle becomes a wide ellipse |
SVG preserveAspectRatio explains every value.
What scales and what does not
Everything inside the viewBox scales together: shapes, stroke widths and text. Two consequences are worth planning for.
Lines get thinner as the SVG shrinks. To hold a stroke at the same thickness on screen whatever the scale, add vector-effect="non-scaling-stroke" to the shape.
Text gets smaller too. A label that reads well at 800 pixels may be unreadable at 300. Either keep the words out of the SVG and in the page’s HTML, or change the drawing at small sizes, as described next.
A logo that changes with its width
An SVG file can contain a <style> block with media queries. When the file is shown with <img>, the queries measure the image’s own box, not the browser window. That lets one file drop detail when it is drawn small. A complete file:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 60">
<style>
@media (max-width: 120px) {
.name { display: none; }
}
</style>
<circle cx="30" cy="30" r="24" fill="teal"/>
<rect class="name" x="70" y="20" width="120" height="20" fill="navy"/>
</svg>
The circle stands for a logo’s mark and the bar for its name. Shown in an <img> wider than 120 pixels, both appear. At 120 pixels or narrower the bar is hidden and only the mark is left.
Inline SVG behaves differently: there the same media query measures the browser window, like any other CSS on the page. Use the page’s own style sheet and classes to adapt an inline SVG.
Common problems
| What you see | Cause | Fix |
|---|---|---|
| The SVG is cropped when the page narrows | No viewBox | Add viewBox="0 0 W H" using the original width and height |
| It stays one size | Fixed width and height, and no CSS | Add max-width: 100%; height: auto |
| Empty bands above and below | The height is fixed while the width shrinks | height: auto |
An inline SVG or an <img> vanishes, at 0 by 0 | It has a viewBox but no width, inside a float, an inline-block or another box that shrinks to fit its contents | Give the SVG, or its parent, a width |
| The SVG is enormous on wide screens | A viewBox-only SVG fills all the width on offer | Add max-width |
| Lines look too thin on a phone | Strokes scale down with the drawing | vector-effect="non-scaling-stroke", or a thicker stroke |
| A small gap under the SVG | An inline SVG sits on the text baseline | display: block |
| The media query in the file is ignored | The SVG is inline, so the query measures the window | Use <img>, or move the rule to the page’s CSS |
To find out whether a file has a viewBox, open it in the SVG viewer, which lists it beside the size. Resize SVG adds a missing viewBox when it sets a new size. SVG viewBox explained covers adding one by hand.
Questions
Should the width and height attributes be removed? Not necessarily. With a viewBox present they act as the natural size, and CSS overrides them. Removing them makes the SVG fill its container by default, which is right for a full-width illustration and wrong for a small icon.
Is the padding trick for keeping proportions still needed? No. Current browsers take the proportions from the viewBox, so height: auto is enough.
Do responsive SVGs matter for cutting machines? No. A cut file should have a real size, with units on its width and height. A file exported for the web with no size at all is the kind that opens at an unexpected size in cutting software: SVG size and units explains why.