SVG: XML for Drawing

Scalable Vector Graphics (SVG) is a web-friendly vector file format for describing two-dimensional based vector graphics.

Essentially, SVG is to graphics what HTML is to text.


Besides, SVGs are written in XML code, meaning they store any text information as literal text.

All elements are defined between <svg> tags, as in:

<svg xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

or, more generally:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  ...
</svg>

Being a vector file format means that it can be scaled up or down without losing any of its resolution.


The functionality in SVG partially overlaps the graphic operators of PostScript and seems to improve on them and make right some of its shortcomings. For instance, SVG recognizes the whole gamut of units (mm, cm, pixels, points etc.), whereas PostScript only recognizes points.

A Simple Example in SVG

Below there is the code for a web page without an xml declarations (<?xml version="1.0" encoding="UTF-8"?>) or an SVG namespace declaration inside an opening tag (xmlns:svg="http://www.w3.org/2000/svg")...

<html> <body> <h1>My first SVG</h1> <svg width="100" height="100"> <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /> </svg> </body> </html>

, which should show a page with a header and a yellow-filled, green-lined triangle like the picture below.

Coordinates

SVG pictures are painted on an infinite canvas. Here we'll discuss how you tell a viewer program where your picture is located, what its dimensions are, and how you locate points within that area.

Coordinates

In a normal cartesian coordinate system the point x=0, y=0 is at the lower left corner of the graph. In the SVG coordinate system the point x=0, y=0 is the upper left corner. The y-axis is thus reversed compared to a normal graph coordinate system. As y increases in SVG, the points, shapes etc. move down, not up.

The Viewport

The area of the canvas that your document intends to use is called the viewport. You establish the size of this viewport with the width and height attributes on the <svg> element. The values of these attributes can be simply a number, which is presumed to be in pixels. This is said to be specified in user coordinates. You may also specify width and height as a number followed by a unit identifier.

Examples:

<svg width="200" height="150"> <svg width="200px" height="200px">

or:

<svg width="2cm" height="3cm">

(If you have one <svg> element nested within another <svg> element, the nested tag may also specify its width and height as a percentage, measured in terms of the enclosing element.)

Using Default User Coordinates

When you do not use unit specifiers on your <svg> element, the viewer sets up a coordinate system where the horizontal, or x-coordinate, increases as you go to the right, and the vertical, or y-coordinate, increases as you move vertically downward. The upper left corner of the viewport is defined to have an x- and y-coordinate of zero. This point, written as (0, 0) is also called the origin.

Specifying User Coordinates for a Viewport (viewBox)

In the examples so far, numbers without units have been considered to be pixels. Sometimes this is not what you want. For example, you might want to set up a system where each user coordinate represents one-sixteenth of a centimeter. (We're using this coordinate system to prove a point, not to show a paragon of good design.) In this system, a square that is 40 units by 40 units will display as 2.5 centimeters on a side.

To accomplish this effect, you set the viewBox attribute on the <svg> element. The value of this attribute consists of four numbers that represent the minimum x-coordinate, minimum y-coordinate, width, and height of the user coordinate system that you want to superimpose on the viewport.

So, to set up the sixteen-units-per-centimeter coordinate system for a four centimeter by five centimeter drawing, you'd use this starting tag:

<svg width="4cm" height="5cm" viewBox="0 0 64 80">

Example using a viewBox:

<svg width="4cm" height="5cm" viewBox="0 0 64 80">
  <rect x="10" y="35" width="40" height="40" style="stroke: black; fill: none;" />
  <!-- roof -->
  <polyline points="10 35, 30 7.68, 50 35" style="stroke:black; fill: none;" />
  <!-- door -->
  <polyline points="30 75, 30 55, 40 55, 40 75" style="stroke:black; fill: none;" />
</svg

Preserving Aspect Ratio

In the previous example, the aspect ratio, or ratio of width to height, of the viewport and the viewBox were identical (4/5 = 64/80). What happens, though, if the aspect ratio of the viewport and the viewBox are not the same, as in this example, where viewBox has an aspect ratio of one to one, but the viewport has an aspect ratio of one to three?

There are three things that SVG can do in this situation:

    Scale the graphic uniformly according to the smaller dimension so the graphic will fit entirely into the viewport. In the example, the picture would become half its original width and height. We'll show you examples of this in a further section. Scale the graphic uniformly according to the larger dimension and cut off the parts that lie outside the viewport. In the example, the picture would become one and a half times its original width and height. We'll show you examples in another section. Stretch and squash the drawing so that it fits precisely into the new viewport. (That is, don't preserve the aspect ratio at all.) We will cover this in another section.

In the first case, since the image will be smaller than the viewport in one dimension, you must specify where to position it. In the example, the picture will be scaled uniformly to a width and height of 45 pixels. The width of the reduced graphic fits the width of the viewport perfectly, but you must now decide whether the image meets (is aligned with) the top, middle, or bottom of the 135-pixel viewport height.

In the second case, since the image will be larger than the viewport in one dimension, you must specify which area is to be sliced away. In the example, the picture will be scaled uniformly to a width and height of 135 pixels. Now the height of the graphic fits the viewport perfectly, but you must decide whether to slice off the right side, left side, or both edges of the picture to fit within the 45-pixel viewport width.

Specifying Alignment for preserveAspectRatio

The preserveAspectRatio attribute lets you specify the alignment of the scaled image with respect to the viewport, and whether you want it to meet the edges or be sliced off. The model for this attribute is:

preserveAspectRatio="alignment [meet | slice]"

where alignment specifies the axis and location, and is one of xMinYMin, xMinYMid, xMinYMax, xMidYMin, xMidYMid, xMidYMax, xMaxYMin, xMaxYMid, or xMaxYMax. This alignment specifier is formed by concatenating an x-alignment and a y-alignment as shown in the table. The default value for preserveAspectRatio is xMidYMid meet.

So, if you want to have the picture with a viewBox="0 0 90 90" fit entirely within a viewport that is 45 pixels wide and 135 pixels high, aligned at the top of the viewport, you would write:

<svg width="45px" height="135px" viewBox="0 0 90 90"
        preserveAspectRatio="xMinYMin meet">

This is all fairly abstract; here are some concrete examples that show you how the combinations of alignment and meet and slice interact with one another.

SVG Units

(Angles are given in degrees, not radians.)