
viewBox and viewport in SVG
The height and width attributes define the viewport of the SVG element. The viewport can be thought of in the same way as the viewport in your browser. It defines the visible dimensions of the SVG document. The dimensions of the underlying SVG document can be larger than the viewport and, as with HTML, elements can be offscreen entirely. Everything that is visible is within the dimensions of the viewport.
If you just set the height and width attributes of an SVG element and don't use the viewBox attribute, it will behave in a manner equivalent to what you would expect if you've worked with CSS. In the case of the previous example, the viewport coordinate system will start with the coordinates (0,0) and will end at (350, 150).
In this case, each user unit will default to one pixel on the screen.
The viewBox attribute lets you change that initial viewport coordinate system. By redefining that coordinate system, you can shift and scale the underlying SVG document in interesting ways. Instead of trying to describe what's possible, let's look at some examples.
In every example we've shown so far, we've used the viewBox attribute and it's been set to match the dimensions of the height and width attributes of the viewport. What happens if we change the height and width attributes of the SVG element and don't change viewBox to match? Adding a second SVG element with new height attributes and width equal to double the original values creates a second version of the image at twice the size:
<svg xmlns="http://www.w3.org/2000/svg" width="700" height="300"
viewBox="0 0 350 150" version="1.1"> <circle cx="100" cy="75" r="50" fill="rgba(255,0,0,1)"/> <rect x="200" y="25" width="100" height="100"
fill="rga(0,0,255,1)"/> </svg>
This is what it looks like in a browser. As you can see, the viewport has been doubled, but since viewBox has the same dimensions, the exact same coordinates on the circle and rect elements create a scaled-up version of the image. In this case, the user units are no longer equivalent to one pixel, but the calculations inside the SVG element remain the same:

You could scale this up as large as you like and it would render perfectly.
What happens if we adjust the viewBox attribute itself? What does the value of the viewBox attribute represent?
The viewBox attribute takes four parameters: min-x, min-y, width, and height. min-x and min-y define the upper-left corner of viewBox. Now, width and height determine the width and height of that viewBox. Playing with these values shows how they interact with the height and width of the viewport. The first two examples change the x and y positions of the viewport's coordinate system. The first example offsets it by 20% (70 and 30 are 20% of the SVG width and height) in the positive direction. The second example offsets it by 20% in the negative direction. The third example changes the width and height of the viewBox attribute, shrinking it by half:
<svg xmlns="http://www.w3.org/2000/svg" width="350" height="150" viewBox="70 30 350 150" version="1.1"> <circle cx="100" cy="75" r="50"
fill="rgba(255,0,0,1)"/> <rect x="200" y="25" width="100"
height="100" fill="rga(0,0,255,1)"/> </svg>
<svg xmlns="http://www.w3.org/2000/svg" width="350" height="150"
viewBox="-70 -30 350 150" version="1.1"> <circle cx="100" cy="75"
r="50" fill="rgba(255,0,0,1)"/> <rect x="200" y="25" width="100" height="100" fill="rga(0,0,255,1)"/> </svg>
<svg xmlns="http://www.w3.org/2000/svg" width="350" height="150"
viewBox="0 0 175 75" version="1.1"> <circle cx="100" cy="75" r="50"
fill="rgba(255,0,0,1)"/> <rect x="200" y="25" width="100" height="100"
fill="rga(0,0,255,1)"/> </svg>
Rendered in the browser, you can see the effect of those changes to the viewBox attribute. The offsets move the circle and square closer relative to the upper left-hand corner of the viewport. Shrinking the size of the viewBox attribute by half and keeping the size of rect and circle the same, effectively doubles the size of the rendered elements. The viewport stays the same size so the viewBox attribute and associated user units scales up by a factor of 2 to fit. All the elements inside it are scaled up as necessary:

The following diagram shows what's at work in a little more depth (the black outline overlay represents the viewBox viewport):

There is still more to learn about positioning in SVG, but we're going to tackle those topics as they arise throughout this rest of the book.
Now let's take a deeper look at some of the other elements that make up the SVG experience.