In this tutorial:
See Understanding SVG Coordinate Systems, W3 Spec and How to Scale SVG for more information.
ViewPort
The visible area of the SVG image is called a viewPort.
We can specify the size of the viewPort using the width and height attributes of the <svg> element or by using CSS. This coordinate system starts at the top-left corner (defined as 0,0). Increasing the x-coordinate will result in moving rightwards, while increasing the y-coordinate will result in moving downards. Note that if width and height are not provided, the value used will be as though '100%' was provided (100% of the SVG container).
ViewBox
The SVG drawing space is effectively infinite: you can draw at any coordinate point anywhere in an SVG document. However, for display purposes the document usually has to have some sort of dimensioning, like a frame around a canvas painting. That’s where viewBox comes in.
The viewBox does many things:
- It defines the aspect ratio of the image.
- It defines how all the lengths and coordinates used inside the SVG should be scaled to fit the total space available.
- It defines the origin of the SVG coordinate system, the point where x=0 and y=0.
viewBox is the user coordinate system, which is, if not specified, identical to the viewPort. We can change it by specifying viewBox attribute in the <svg> element.
viewBox attribute value is a list of four numbers, separated by whitespace or commas: x, y, width, height. The most common way you’ll see viewBox applied is something like the following:
<svg viewBox="0 0 200 100">
The width is the width in user coordinates/px units, within the SVG code, that should be scaled to fill the width of the area into which you're drawing your SVG (the size of SVG - called viewPort).
Likewise, the height is the number of px/coordinates that should be scaled to fill the available height.
The x and y numbers specify the coordinate, in the scaled viewBox coordinate system, to use for the top left corner of the SVG viewPort. (Coordinates increase left-to-right and top-to-bottom, the same as for identifying page locations in JavaScript). For simple scaling, you can set both values to 0. However, the x and y values are useful for two purposes: to create a coordinate system with an origin centered in the drawing (this can make defining and transforming shapes easier), or to crop an image tighter than it was originally defined.
Example:
Below are 3 examples. All rectangles have exactly the same SVG definition. The difference is in the viewBox definition.
On the left, viewBox is Identical to viewPort. If ViewBox is not specified, the default size of the viewBox is the size of the viewPort.
In the middle, every 1 unit in the coordinates used in the rectangle inside the <svg> corresponds to the real 200/100 = 2 pixels in the width, and 200/100 = 2 pixels in the height. Thus, the same rectangle is proportionally scaled inside the viewPort by 2. Note that we calculate the width scaling by dividing the width of the viewPort by the width of the viewBox. For the height scaling we will use height values.
In the last example, the ratio is 100/200 = 0.5. Thus, every 1 unit in the coordinates used in the rectangle inside the <svg> coresponds to 0.5 actual pixels. Thus the same rectangle is a half of the original one, the left margin is the half of the original and so also the top margin.
<svg width="100" height="100"
viewBox="0 0 100 100"
style="border: 1px solid #d30b0b;">
<rect x="20" y="30"
width="60" height="40"
fill="#d30b0b"/>
</svg>
<svg width="200" height="200"
viewBox="0 0 100 100"
style="border: 1px solid #d30b0b;">
<rect x="20" y="30"
width="60" height="40"
fill="#d30b0b"/>
</svg>
<svg width="100" height="100"
viewBox="0 0 200 200"
style="border: 1px solid #d30b0b;">
<rect x="20" y="30"
width="60" height="40"
fill="#d30b0b"/>
</svg>
Example:
In the following examples, the circle on the right is defined exactly as the circle on the left. The viewBox of the right circle is shifted left by -50 in both directions. Thus, the unit 0 inside the <svg> corresponds to the actual -50 pixels.
<svg width="100" height="100"
viewBox="0 0 100 100"
style="border: 1px solid #d30b0b;">
<circle cx="0" cy="0" r="50"
fill="#d30b0b"/>
</svg>
<svg width="100" height="100"
viewBox="-50 -50 100 100"
style="border: 1px solid #d30b0b;">
<circle cx="0" cy="0" r="50"
fill="#d30b0b"/>
</svg>
Example:
The following example demonstrates how to center the svg:
- Center the HTML container.
- Give a class to your svg tag (svg-center in this example).
- Set svg viewPort size to 100% of the container (it is the default if svg size is not specified). By doing the above, the defined viewBox will be stretched to the container size.
- Define viewBox according to the units inside the svg. In the first example we define 400x400 pixel. In the second 800x800.
- Define svg elements inside the defined viewBox. In the first example inside the 400x400. In the second inside 800x800. Pay attention that the circle is centered inside the viewBox area, and therefore inside the viewPort.
- Use preserveAspectRatio if required. Note that in the two first examples below aspect ratio is preserved by default.
See How to Scale SVG for more details.
HTML:
<div class="container">
<svg class="svg-center" viewBox="0 0 400 400">
<circle cx="200" cy="200" r="50" fill="#d30b0b" />
</svg>
</div>
<div class="container">
<svg class="svg-center" viewBox="0 0 800 800">
<circle cx="400" cy="400" r="50" fill="#d30b0b" />
</svg>
</div>
<div class="container">
<svg class="svg-center" viewBox="0 0 400 400" preserveAspectRatio="none">
<circle cx="200" cy="200" r="50" fill="#d30b0b" />
</svg>
</div>
CSS:
.container {
width: 200px;
height: 100px;
float: left;
margin-right: 20px;
margin-bottom: 20px;
border: 1px solid #d30b0b;
}
.svg-center {
width: 100%;
height: 100%;
}
preserveAspectRatio
If the viewPort and the view box does not have the same aspect ratio (width-to-height ratio), you need to specify how the SVG viewer (e.g. the browser) has to display the SVG image. You do so using the preserveAspectRatio attribute of the <svg> element. preserveAspectRatio has no effect unless a viewBox exists to define the aspect ratio of the image. See How to Scale SVG for more details.