ViewBox - A Window Into The Soul Of SVG


I like to think of myself as a geek in the sense that I like to understand how things work. This is true of physical things, like quadcopters and 3d printers, but being a software guy it's even more true of software. Thus, when I first started playing with SVG files, I wasn't primarily interested in using gui drawing programs, I wanted to put all the pieces together myself and see what works and what doesn't. So, in case this is the sort of thing that interests you, I'm going to delve into the details a bit. If you really want technical details, you could always try here, bit while I find that site surprisingly readable and useful, it still a bit overwhelming when starting out.

The main point of SVG is the S, as in Scalable. It is designed to be scaled to any size without losing precision. It does this by describing points of interest in a vector space. While these points may seem just like pixels on a Canvas element, it's not quite the same. On a canvas at the most fundamental level you're turning pixels on and off, which when scaled up look like tiny rectangles. In SVG, you're describing lines and shapes, connecting at certain points, with various sizes. Nevertheless, the way these vectors and shapes are described is similar to what you do when drawing on a canvas element.There is a grid system of x and ycoordinates, but rather than describing pixels, they form the space in which vectors are described. The bounds of this vector space are not limited to any size in particular, but the window into this space is described by the viewBox, which is specified as an attribute on the svg element, like this:

<svg viewBox="0 0 100 100">

The viewBox is a rectangle described by 4 numbers. The first two numbers are the x and y coordinates of the upper left corner, while the next two numbers are the width and height, respectively. Note that the positive y direction is down, not unusual when talking about canvas, but upside down from what we all learned in Math class. Also note that the units are not pixels, but points in the vector space, thus you don't put 'px' or any other units after them, as you would in CSS styling. Though typically the objects described are contained within the viewBox, there's no reason the y need to be.

The dimensions of the viewBox are essentially arbitrary, so I like to choose them forthe convenience of whatever shapes I'm working with. I might choose width and height to be 100, to make decimal math easy, or if I want to divide the space into thirds, I might choose a multiple of 3. If I want to emulate an HD screen, I c an do 1600x900 to get the correct aspect ratio. If I want something symmetric about the origin, I could choose something like "-100 -100 200 200" to get a square around the origin of the coordinate system. The size of the viewBox is completely independent of the size of the actual element, which can be set with HTML attributes or with CSS styling. For that matter, while it is usually described using integers, you can just as well use floating point numbers, though in practice I haven't had a reason to do that yet.

Of course, in the end, you'll need to make things appropriate sizes for your viewBox considering how big your svg element is. It's useless to have a 1600x900 viewBox containing a circle of radius 10 if the resulting SVG element is only 100px wide. The circle would end up being 1/16th the size of a pixel, so you wouldn't see much. So while the width and height are technically independent of the viewBox dimensions, one does need to consider the final size of things when all that mapping is done.

This picture illustrates three different viewBoxes over the same SVG vector space:

Viewport Illustration

There's a warm yellow sun in the center of the coordinate system, but each viewBox shows it a different view of it, with size, position and clipping varying depending on your point of view. The actual SVG element, the circle, remains completely unchanged. I've created a JSFiddle so you can try out different viewBoxes with this same element. If you change the viewBox settings on the svg element in the html window you can recreate these viewBoxes, or create other ones to see what I mean.

Unfortunately, the viewBox attribute is not something that can be set using CSS styling (I did try), but it can still be used for animation effects, with the help of some Javascript. I created another JSFiddle that illustrates this effect. If you click on the SVG element, it should zoom out and in as well as translate. Again, none of the elements within the SVG are changed, only the viewBox attribute.

One final note, while the width and height attributes are separate from the viewBox settings, overspecifying them can get tricky.  On top of that, I see different results in different browsers.  The safest thing to do for now is to set width and height to have the same aspect ratio as the viewBox, then things seem to look OK.  On the positive side, Firefox seems to handle things OK.

Get started with the Intel XDK

Download Now

For more complete information about compiler optimizations, see our Optimization Notice.