Using SVG with CSS3 and HTML5 — Supplementary Material

Example code and online extras for the O'Reilly Media book by Amelia Bellamy-Royds, Kurt Cagle, and Dudley Storey.

The Limits of Numbers in SVG

SVG describes shapes and layouts with mathematical precision. The perfect curve of a path exists separate from the limited pixels used to display it. But in order to convert your mathematical curves into visible pixels, the computer needs a binary number to calculate with. And numbers in computers have their limits.

The SVG coordinate plane may be theoretically infinite, but you’ll fall off the edge of the world if you exceed the size of a 32-bit (single-precision) floating point number. The SVG specifications don’t require browsers to keep track of any coordinates larger than that.

Theoretically, that means that you should only have to worry about too-big numbers if you’re navigating in the neighborhood of 1 trillion trillion trillion units.

In reality, when drawing SVG in web browsers, even much smaller numbers can cause problems.

Even if all web browsers used floating point arithmetic (like they are supposed to), you can get in trouble with medium-sized numbers if you need them to be precise to many decimal places.

Floating point numbers encode the value of the number (the significand) separately from its size (the exponent, equivalent to the number of digits left or right of the decimal place, but in binary format). Floats can therefore store very large or very small numbers—but they can’t reliably add or subtract the two.

Tip

If you ever do need to use numbers in the trillions—or trillionths—you’ll be glad to know that you can use scientific notation to express really large numbers (like 6.022e23, the Avogadro number) or really small numbers (like 6.626e-34, the Planck constant). But don’t expect those numbers to be stored with high precision—only the first few digits would remain accurate.

Using single-precision floats, SVG viewers are not expected to correctly draw differences between two values finer than 1/4,000,000 of the larger number (that’s 1 over 2 to the power of 22, approximately). In practice, very few achieve even that.

Now, even with the latest high-resolution widescreen monitors, it’s unlikely that you will be able to display the difference between 4 million and 4 million plus one, anyway.

The issue with mid-sized numbers arise when you zoom in to coordinates with large values but small differences between them. In other words, trying to use latitude and longitude degrees to map a city block (with individual buildings measured in hundred-thousandths of a degree) would cause floating-point errors.

But that’s not your biggest problem.

Your biggest problem is that many low-level vector graphics languages were designed to work with screen coordinates, not scientific ones. SVG viewers that build upon these graphics languages are limited in the numbers they can handle.

The numerical precision limits described above are the theoretical ones, based on the SVG specifications. If your SVG display software follows the SVG specifications, it would use 32-bit (“single precision”) floating-point numbers for all calculations, and 64-bit (“double precision”) for calculating transformations.

However, some low-level vector graphics languages use fixed-point numbers. And many web browsers use those low-level languages to draw SVG.

Fixed point means that only the value is stored, and the exponent is always the same; larger numbers or tiny decimals cannot be encoded at all.

Warning

For reliable results cross-browser, use numbers with no more than 2 digits after the decimal and four digits before it.

Also, Firefox (as of version 55) does not correctly calculate <svg> aspect ratios with a viewBox where the width or height is less than 1, even though it may correctly draw the scaled graphics.

If you stick with coordinates that are reasonably close to the default scale of one unit per pixel—and with graphics that will fit on your screen—you don’t usually have to worry about the precision and range of possible numbers. However, if you’re working with technical coordinates that have a meaning separate from their visual display, you will often need to scale them to screen dimensions before using them in your SVG code.

If you are creating a large, detailed SVG drawing (such as a map), you may need to break it into tiles with their own coordinate system, instead of using a continuous coordinate system for the entire map. Each point should use decimals no more precise than 0.01, and the largest numbers should be no bigger than ±5,000. You can then use transformations and nested coordinate systems to position your tiles correctly in the overall layout.