SVG Tutorial

SVGs are Scalable Vector Graphics. They are an increasing popular form of image, particular for use on the web.

SVGs are called Vector graphics because they define graphics as a series of vectors, unlike raster graphics, which define graphics as a series of pixel colours. This means if an image contains a black line, rather than setting every pixel along that line to be black, a description of the line is stored. When you view an SVG, the program you're using to view it, for example your web browser, looks at the description and calculates the colour of each pixel. The advantage of this approach is that it makes graphics Scalable: you can zoom in on the image as much as you like and it will never pixelate because the image will be re-rendered after each zoom.

In this series of tutorial I aim to cover the basics of drawing shapes in SVG. For complex drawings you may want to try Inkscape (which is free) or Adobe Illustrator. As much as possible, I hope to include interactive demos like the one below (created using SVG) to allow you to drag the control points around and see what the what code would create that shape.  I hope this will give you a more intutive sense of what each attribute does. This style of demo was very much inspired by Bret Victor, and if you have a spare hour, I recommend watching this video.

At some point I'd like to make a tutorial covering SVG scripting (I started one here). For some more advanced SVG examples check out:

SVGs on the web

Guest post by Bauke Roesink

The guys at PSDtoWP.net would like to change developers' mindsets about SVG. SVG and its use on the web were already recommended by W3C about 13 years ago. Despite the recommendation, many developers still don't choose SVG automatically. Since the usage of SVG on the web has a lot of advantages, I would like developers not only to dive deep into SVG but also to use SVG files during their daily tasks. The reason is pretty straightforward: SVGs have many benefits over JPG, PNG and GIF files. As a result Bauke from psdtowp.net created a fancy SVG infographic which not only defines SVG but which also explains the various benefits and the exact way SVG should be used on your websites.


The ultimate SVG guide

The SVG Document

SVG is based on XML so consists of a series of nested elements within an SVG element. You can create an svg file by creating a new text file and changing its file extension to .svg. You can edit its contents in any text-editor.

Elements

Elements consist of a start tag, which looks something like <tag>, some contents, and an end tag, which looks like </tag>. Tags must always be closed. If an element does not contain any contents (which is more in SVG than in most XML documents), then is can simply be a self-closing tag, which looks like this <tag />. Some examples of tags used in SVG are <line>, <rect> <text> and <style>. The contents of elements can be text (for example, in <text> tags) or other elements (for example in the group tag, <g>).

Attributes

Tags may also contain attributes, which define the properties of that element. Attributes have the form name="value", and are put in a start tag, after the tag's name but before the closing '>'. An element can contain any number of attributes and each must be separated by a space (or any amount of whitespace, including new lines). Elements have specific attributes that determine their appearance. If any of these attributes is missing it will default to zero. For example, a line is defined by the attributes x1, y1, x2 and y2. Changing the value of these attributes changes the appearance of the element. [EDIT: You also have to set the stroke to equal a colour, otherwise the line won't show up.]

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">

    <line x1="40" y1="30" x2="240" y2="100" stroke="black" />

</svg>

There are additional attributes that can control the style of elements, which I will describe later. Attributes that have no function are ignored (which can be useful for scripting effects).

The SVG tag

As stated at the beginning of this post, an SVG consists of element inside an SVG element. An SVG must therefore start with <svg> and end with </svg>. Often SVGs will start with a DOCTYPE declaration, but according to these SVG authoring guidelines there's no need. Instead you should include the following attributes which tell the program interpreting your document how to do so:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">

You can also include width and height attributes here which will determine the dimensions of the SVG. The following is an example of a complete SVG document containing a line. In the next tutorial I will cover all the shape elements.

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg"
     width="400" height="180" >

    <line x1="40" y1="30" x2="240" y2="100" stroke="black" />

</svg>

SVG Shapes

There are six SVG shape elements. They never have any contents and are defined by specific attributes, which default to zero if not specified. The six elements are:

  • line
  • rect
  • circle
  • ellipse
  • polyline
  • polygon

In all cases coordinates are given with the top left corner as (0, 0) with the x-axis increasing rightwards and the y-axis increasing downwards. The units of attributes is pixels, but this can be changed by using the SVG viewBox attribute. The order of attributes in not important.

In all of the examples below you can drag the control points (shown as coloured circles) to change a shape's attributes or you can click on an attribute's value and drag horizontally to change it.

Line

The line element is defined by four values: x1 and y1 define the coordinate of the start point; x2 and y2 define the coordinates of the end point.

Rect

The rect element is defined by four values: x and y define the coordinate of the top left corner; width and height unsurprisingly define the width and height. They must be positive. There are also rx and ry attributes which define how rounded the corners are, but I've not got an example of that yet.

Circle

The circle element is defined by three values: cx and cy define the coordinate of the centre; r defines the radius.

Ellipse

The ellipse element is defined by four values: cx and cy define the coordinate of the centre; rx defines its axis in the x direction; ry defines its axis in the y direction.

Polyline and Polygon

Polyline and polygon are both defined by a single attribute: points. This attribute is a series of comma- or space- separated coordinates and are very similar to the SVG path, which is the subject of the next tutorial. The difference between polyline and polygon is that a polygon is closed, so an additional line is created between the first and final coordinates.

Paths

While SVG shapes are good for simple images, any image for complex curves will require a path element. A path element has a d atrribute which contains a sequence of drawing commands. These commands have single letter codes and may be followed by numerical parameters. Uppercase commands, indicate parameters are absolute values, lowercase commands indicate that parameters of relative values. The commands are:

  • M/m (move to)
  • L/l (line to)
  • H/h (horizontal line to)
  • V/v (vertical line to)
  • Q/q (quadratic curve to)
  • T/s (smooth quadratic curve to)
  • C/c (cubic curve to)
  • S/s (smooth cubic curve to)
  • A/a (elliptical arc to)

There is also the Z/z command, which closes the path, i.e. draws a straight line from the current coordinate to the initial coordination. It doesn't matter make any difference if you use an uppercase or lowercase Z.

Straight lines (L, H, V)

Nearly all paths will start with a M x,y since you will generally want to move to a new starting position. The example below shows how to draw two continuous straight lines by first moving to a point, then using L or l to move to two more points. Both M and L are followed by two digits which define the coordinates. For uppercase commands, this moves the virtual pen to that coordinate, for lowercase commands this moves the virtual pen by those values.

Below is an example of a simple path element and three different ways to create it. Drag any of the nodes to change the code.

Note that you can can use spaces or commas between coordinates and there is no need for spaces between commands or between a command and it parameters. You can even do weird things like M0.5.5 which will move the pen to coordinate (0.5, 0.5). As with several other commands, once you have used the L command once, any subsequent pairs of coordinates will be considered part of additional line to commands (as in the final point of the compact example). In general, I think it's safer to explicitly define each command and to use spaces and commas liberally.

The H command is followed by a single value (actually it can be followed by mutliple values, but it is pointless to do so) and will draw a line horizontally such that the pen now has an x-coordinate of that value. The h command moves the pen horizontally by the given value. The y-coordinate of the pen stays the same; the V/v commands more the pen in a similar way vertically. Although these commands require slightly less code that the L/l commands, I have never bothered to use them nor seen anyone else use them.

Quadratic curves (Q, T)

Quadratic Bézier curves have the form Q x1,y1 x2, y2. They start at the current point and curves to (x2, y2), using (x1, y1) as a control point.

The T command can only follow a Q command and it tell the pen create a quadratic curve to a new coordinate using a control point that is symmetrical to the previous one. It's easier to explain with a diagram and in general I don't see any need to use the T command.

Cubic curves

Cubic Bézier curves are similar to quadratic Bézier curves, but the start and end coordinates have separate control points. The cubic curve has the form C x1,y1 x2, y2 x3,y3. It starts at the current point and curves to (x3, y3), using (x1, y1) and (x2, y2) as a control points.

More soon...

Adding an SVG to a webpage

There are four main ways to add an SVG into a webpage.

Inline

Perhaps the easiest method is to paste your SVG element directly into your HTML directly.

<!doctype html>
<html>
  <body>
    <svg width="100" height="50">
      <circle cx="40" cy="20" r="10" />
    </svg>
  </body>
</html>

Although this can be useful if you're generating the HTML somehow, I would generally avoid this method. I think it's much cleaner to have the SVG in a separate file and it make it much easier to add to different pages or email to someone. There can also be issues with interactivity - since the SVG is not separate, mouse events are measured relative to the surrounding HTML and not the SVG, which makes them harder to deal with.

For example, click on the SVG below to see where value of the evt clientX and clientY attributes.

iframe

You can add your SVG using an iframe. This method is generally frowned upon and is not allowed in HTML4. It also creates a weird border around the image.

<iframe src="svgfile.svg" />

object

This is the method I tend to use. I can't see any difference between it and embed.

<object data="svgfile.svg" type="image/svg+xml"></object>

embed

This is pretty much the same as above.

<embed src="svgfile.svg" type="image/svg+xml" />

Styling Elements

There are three different ways you can style an SVG element: using individual attributes, using the style attribute and using CSS. My preferred method is to use CSS, which, like CSS for HTML, has the advantage of making it easy to change the styling of multiple elements at once. I will also use individual attributes when it is simpler and if I intend to change the styling with a script. I avoid using the style attribute and can see no reason to use it.

Individual attributes

You can add attributes to elements to control it's style. For example, adding stroke-width="2" to an element will change the width of its stroke to 2 pixels. The most common styling attributes are:

  • fill = "colour" (default = "black")
  • stroke = "colour" (default = "none")
  • stroke-width = "number" (default = "1")
  • opacity = "number" (default = "1")
  • font-family = "font-name(s)" (default = [variable])
  • font-size = "number" (default = "medium")

You can find a complete list of all the styles here.

The style attribute

The style attribute takes all the individual attributes and concatenates them into the value of a single attribute. Different styles are separated by a semi-colon (;) and the key is separated from the value with a colon(:). For example, you could create a blue circle with a thick red border, like this:

<circle cx="40" cy="40" r="10" fill="blue" stroke="red" stroke-width="3"/>

Or like this:

<circle cx="40" cy="40" r="10" style="fill:blue; stroke:red; stroke-width:3;"/>

Although it can be more compact to write a lot of styles this way, it is harder to read and much harder to change with a script.

To be continued...

An example using CSS: