This article is a full explanation on how and when to use the SVG viewBox.

Introduction

The viewBox property is like a camera in a 2D scene, it allows you to zoom in and out and focus only on certain part of the svg.

Definition

A viewBox value consists of 4 integers separated by whitespaces:

viewBox="xPosition yPosition width height"
  • xPosition: The X (horizontal axis) position of the top left corner of the viewBox
  • yPosition: The Y (vertical axis) position of the top left corner of the viewBox
  • width: The width of the portion of the entire SVG we want to capture
  • height: The height of the portion of the entire SVG we want to capture

Let’s look at examples.

Examples

Base example

This is the base SVG we are going to use throughout this course.


And here is the corresponding SVG code:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
width="100" height="100" style="border: solid 1px grey">
<defs>
<radialGradient id="grad">
<stop offset="10%" stop-color="gold"/>
<stop offset="95%" stop-color="green"/>
</radialGradient>
</defs>
<circle fill="url(#grad)" cx="50" cy="50" r="50"/>
</svg>

We have a 100px by 100px svg canvas which contains a 100px diameter disc centered in (50, 50).

Identity

In our first example, let’s create a viewBox that is placed at (0, 0) (top left corner) and looks at a 100px by 100px portion of our SVG. In other words, it does not do anything since it is the same as the SVG Element size… (for now)


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
width="100" height="100" viewBox="0 0 100 100" style="border: solid 1px grey">
[...]
<circle fill="url(#grad)" cx="50" cy="50" r="50"/>
</svg>

Zoom In

We leave the viewBox at (0, 0) but only look at the first 50px by 50px part of the SVG.


viewBox="0 0 50 50"

Imagine the camera zooming at the first quarter and displaying that in a 100x100 SVG Element.

Zoom Out

We leave the viewBox at (0, 0) but look at a bigger area of the SVG (200px by 200px).


viewBox="0 0 200 200"

Translation

This time around, we won’t modify the size of the area we want to look at (100px by 100px) but we will move the top left corner of the viewBox to the middle of the disc which is located at (50, 50).


viewBox="50 50 100 100"

It is possible to use negative values for the the X and Y position of the viewBox (it is not possible to use negative values for the width and height though).

Aspect Ratio

In all the examples so far, we have kept the aspect ratio. Let’s see what happens if we zoom out more on one dimension.


viewBox="0 0 200 100"

So what happened here, is we took a 200px by 100px viewBox (in red below) out of our initial SVG and resized it to fit in our 100px by 100px SVG HTML element:


By default, the aspect ration is preserved, which is why the disc and viewBox height is also divided by half. You should also note that when auto resizing to preserve the aspect ratio, the browser centers the figure.

Stretch

The next logical question would be: why if do not want to preserve the aspect ratio but stretch the disc into an ellipse instead.

Reusing the example above, this is done by adding an extra element to the <svg> HTML element: preserveAspectRatio="none"


viewBox="0 0 200 100" preserveAspectRatio="none"

The Aspect Ration is not preserved here, as a result, the circle is compressed at the width is reduced by half but the height remains the same.

“Meet” Property

The meet property is another possible value for preserveAspectRatio. It indicates that the aspect ration should be preserved and that all edges should remain contained within the viewBox.

In the situation where you want to keep the aspect ratio, you might also want to control the position where the final vector is placed (centred by default). This is why the meet property should be paired with another list of keywords to specify the final placement of the vector.

Property Place
xMinYMin Top Left
xMidYMin Center Left
xMaxYMin Bottom Left
xMinYMid Top Center
xMidYMid Middle
xMaxYMid Bottom Center
xMinYMax Top Right
xMidYMax Center Right
xMaxYMax Bottom Right

Examples

With an horizontal viewBox: (xMin, xMid and xMax are equivalent)

viewBox="0 0 200 100" preserveAspectRatio="xMidYMin meet"

viewBox="0 0 200 100" preserveAspectRatio="xMidYMid meet"

viewBox="0 0 200 100" preserveAspectRatio="xMidYMax meet"

With a vertical viewBox: (yMin, yMid and yMax are equivalent)

viewBox="0 0 100 200" preserveAspectRatio="xMinYMid meet"

viewBox="0 0 100 200" preserveAspectRatio="xMidYMid meet"

viewBox="0 0 100 200" preserveAspectRatio="xMidYMid meet"

“Slice” Property

The meet value can be replace with slice. Instead of resizing and containing the edges of the viewBox within the SVG element, the vector is sliced.

I believe that at this point, the examples should speak for themselves.

Examples:

With an horizontal viewBox: (yMin, yMid and yMax are equivalent)

viewBox="0 0 166 100" preserveAspectRatio="xMinYMid slice"

viewBox="0 0 166 100" preserveAspectRatio="xMidYMid slice"

viewBox="0 0 166 100" preserveAspectRatio="xMaxYMid slice"

With a vertical viewBox: (xMin, xMid and xMax are equivalent)

viewBox="0 0 100 166" preserveAspectRatio="xMidYMin slice"

viewBox="0 0 100 166" preserveAspectRatio="xMidYMid slice"

viewBox="0 0 100 166" preserveAspectRatio="xMidYMax slice"

The End

That’s it for my explanations on the SVG viewBox, please let me know if you have any questions, corrections or if I have missed anything.

The code for all the examples above is available on CodePen

See the Pen SVG viewBox examples by Jonathan klughertz (@klugjo) on CodePen.