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:

WantedCSS on the <svg>
Fill the container’s widthwidth: 100%; height: auto
Fill it, but never exceed 600 pixelswidth: 100%; max-width: 600px; height: auto
Keep the size in the width and height attributes, and shrink only when the container is narrowermax-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 hasWith no CSSWith max-width: 100%; height: auto
width, height and viewBoxIts own size, and it overflows a narrow containerIts own size, shrinking to fit
viewBox onlyThe full width of the container, however wideThe same
width and height onlyIts own sizeShrinks 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.

ValueResult
containThe whole drawing fits inside the element
coverThe 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>
preserveAspectRatioIn a box 800 wide and 120 tall
Left outThe drawing is fitted inside: 160 by 120, centred, with empty space either side
xMidYMid sliceThe drawing covers the box. The top and bottom are cropped
noneThe 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 seeCauseFix
The SVG is cropped when the page narrowsNo viewBoxAdd viewBox="0 0 W H" using the original width and height
It stays one sizeFixed width and height, and no CSSAdd max-width: 100%; height: auto
Empty bands above and belowThe height is fixed while the width shrinksheight: auto
An inline SVG or an <img> vanishes, at 0 by 0It has a viewBox but no width, inside a float, an inline-block or another box that shrinks to fit its contentsGive the SVG, or its parent, a width
The SVG is enormous on wide screensA viewBox-only SVG fills all the width on offerAdd max-width
Lines look too thin on a phoneStrokes scale down with the drawingvector-effect="non-scaling-stroke", or a thicker stroke
A small gap under the SVGAn inline SVG sits on the text baselinedisplay: block
The media query in the file is ignoredThe SVG is inline, so the query measures the windowUse <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.