SVG preserveAspectRatio: every value explained
preserveAspectRatio decides how an SVG's viewBox fits a frame of a different shape: fit inside, cover and crop, or stretch. Every value, with examples.
Published
preserveAspectRatio tells an SVG what to do when its viewBox and the frame it is drawn in have different proportions. It has two parts: an alignment such as xMidYMid, and the word meet (fit the whole drawing inside the frame) or slice (cover the frame and crop what overflows). The single value none stretches the drawing to the frame instead. The default is xMidYMid meet: fit inside and centre.
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="100"
viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect width="100" height="100" fill="gold"/>
<circle cx="50" cy="50" r="40" fill="teal"/>
</svg>
This complete file is used for every example below. The drawing is a gold square, 100 units each way, with a teal circle on it. The frame is 300 pixels wide and 100 tall: three times wider than the drawing. As written, the square is drawn 100 pixels wide in the middle of the frame, with 100 empty pixels on each side.
The three behaviours
| Value | What happens in the 300 by 100 frame |
|---|---|
xMidYMid meet | The square is scaled until it just fits: 100 by 100 pixels. Empty bands are left at the sides |
xMidYMid slice | The square is scaled until the frame is covered: 300 by 300 pixels. Only a strip 100 pixels tall is seen, and the rest is cropped |
none | The square is stretched to 300 by 100. The circle becomes an ellipse 240 pixels wide and 80 tall |
meet and slice always scale evenly, so circles stay round. Only none distorts.
The alignment: where the drawing sits
The first part of the value says where the drawing is placed in the frame. It is one word built from an x part and a y part.
| Part | Meaning |
|---|---|
xMin | Left edges together |
xMid | Centred across |
xMax | Right edges together |
YMin | Top edges together |
YMid | Centred up and down |
YMax | Bottom edges together |
That gives nine alignments, from xMinYMin (top left) to xMaxYMax (bottom right). The x is lower case and the Y is a capital, and the spelling must be exact.
With the example file, only one of the two parts has anything to do, because the drawing already fills the frame in the other direction.
With meet, the square fits the height exactly, so the spare room is at the sides and the x part places it:
| Value | The square is drawn |
|---|---|
xMinYMid meet | At the left: pixels 0 to 100 |
xMidYMid meet | In the middle: pixels 100 to 200 |
xMaxYMid meet | At the right: pixels 200 to 300 |
Changing YMid to YMin or YMax makes no difference here. In a tall frame, say 100 wide and 300 tall, it is the other way round: the y part moves the square to the top, middle or bottom, and the x part does nothing.
With slice, the square is 300 pixels each way and the frame shows a strip 100 pixels tall. The y part chooses the strip:
| Value | What is seen |
|---|---|
xMidYMin slice | The top third of the square |
xMidYMid slice | The middle third, through the centre of the circle |
xMidYMax slice | The bottom third |
All the values
preserveAspectRatio accepts none, or one of these nine alignments followed, if wanted, by meet or slice:
| Left | Centre | Right | |
|---|---|---|---|
| Top | xMinYMin | xMidYMin | xMaxYMin |
| Middle | xMinYMid | xMidYMid | xMaxYMid |
| Bottom | xMinYMax | xMidYMax | xMaxYMax |
Leaving off the second word means meet. The alignment cannot be left off: preserveAspectRatio="slice" is not a valid value, and browsers fall back to the default.
It needs a viewBox
On an <svg> element the attribute only acts when the same element has a viewBox. Without one there is no rectangle to fit, the drawing stays at one unit to the pixel, and preserveAspectRatio is ignored. SVG viewBox explained covers the four numbers.
When the viewBox and the frame have the same proportions, every value gives the same picture, because nothing is left over to align or crop.
Where it can be used
| Element | What is fitted |
|---|---|
<svg>, outermost or nested | Its viewBox into its own width and height |
<symbol> | Its viewBox into the size given by the <use> that draws it |
<image> | The picture into the box set by the element’s x, y, width and height |
<pattern> and <marker> | Their viewBox into the tile or the marker box |
<view> | The same, for a view chosen by a link |
On <image> no viewBox is needed: the picture’s own size plays that part. A photograph placed in a box of another shape is fitted inside and centred unless the element says otherwise. preserveAspectRatio="xMidYMid slice" makes it cover the box, and none stretches it.
In an img tag or a CSS background
A standalone SVG file shown with <img>, or as a CSS background, is given a box by the page. If the box and the viewBox differ in shape, the file’s own preserveAspectRatio decides what happens inside the box. Page CSS cannot change the attribute from outside: it has to be edited in the file. What the page can do is treat the whole image as it would a photograph: object-fit: cover on the <img> makes a file that has a viewBox cover the box.
This is why an SVG logo in an <img> that is forced to 300 by 100 pixels is not squashed. With the default it is fitted and centred. To make an SVG stretch to any box, which suits dividers, wavy edges and plain backgrounds, put preserveAspectRatio="none" on the file’s root element. With a CSS background, also set background-size: 100% 100%. SVG as a CSS background image has the rest.
A file with width and height but no viewBox is different: in an <img> of another shape it is stretched to the box, since there is no viewBox for the attribute to work with.
The same thing in CSS terms
| preserveAspectRatio | Nearest CSS for a photograph |
|---|---|
xMidYMid meet | object-fit: contain |
xMidYMid slice | object-fit: cover |
none | object-fit: fill |
| The alignment | object-position |
Setting it with JavaScript
The name is case sensitive in script. Use the capital letters exactly:
document.querySelector('svg').setAttribute('preserveAspectRatio', 'xMinYMin slice');
setAttribute('preserveaspectratio', ...) creates a different attribute that does nothing. In SVG typed straight into an HTML page the browser corrects the capitals. In a standalone .svg file it does not, so the lower case spelling is ignored there too.
Common problems
| What you see | Cause | Fix |
|---|---|---|
| Empty bands beside or above the drawing | meet, with a frame of another shape | Make the frame’s proportions match the viewBox, or use slice to fill it |
| The edges of the drawing are cut off | slice | Use meet, or choose the alignment that keeps the important part |
| The drawing is stretched | none | Remove the attribute |
| The attribute does nothing | No viewBox, or the viewBox and frame are the same shape | Add a viewBox |
slice on its own does nothing | The alignment is missing | Write xMidYMid slice |
| A background SVG will not stretch | The file has a viewBox and the default value | Add preserveAspectRatio="none" to the file and set background-size: 100% 100% |
| Works in HTML, ignored in the .svg file | Lower case spelling | Write preserveAspectRatio with its capitals |
Questions
Does it change the file’s size? No. It only decides how the drawing sits in a frame. The frame comes from width and height or from the page: see SVG size and units.
Does it matter for cutting machines? Rarely. Cut files normally have a viewBox in the same proportions as their width and height, so there is nothing to fit. If a file opens with odd margins, compare the two in the SVG viewer, and trim the frame to the artwork with crop SVG.
Is preserveAspectRatio="none" bad practice? No. It is the right value when a shape is meant to stretch. Strokes stretch with it, so lines become thicker in one direction than the other.
Can the excess be shown instead of cropped with slice? Yes, on inline SVG: the CSS overflow: visible on the <svg> element lets the drawing spill outside its frame.