HTML & CSS
Article
By Craig Buckler

Scalable Vector Graphics: Drawing Basics

By Craig Buckler
Last chance to win! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

In my previous posts we discussed what SVGs are and reasons you should consider SVGs for your project. In this article we’ll look at the basic concepts, document structure and drawing elements.

SVG Co-ordinate Space

An SVG is defined in whatever co-ordinate space you give it. That space does not necessarily relate to pixels, cm, inches or other units because the images are scalable to any dimension.

Optionally, you can define a viewbox which determines the co-ordinates your SVG uses. The following SVGs would look identical:

  • An SVG with a viewbox of 0,0 to 200,100 with a line from 0,0 to 100,50.
  • An SVG with a viewbox of 0,0 to 300,150 with a line from 0,0 to 150,75.

SVG drawing space

Your images are rendered within a viewport, i.e. the whole browser window or a block in an HTML page. By default, an SVG viewbox will stretch in either direction to fill the viewport space. However, you can state that you want the aspect ratio preserved.

Unlike mathematical graphs, the SVG co-ordinate system starts at the top left (usually 0,0) with the x-axis pointing right and y-axis pointing down. Therefore, a point at 100,200 represents 100 units to the right of the left hand edge and 200 units down from the top edge.

SVG Length Units

Lengths in SVG can be specified either as:

  • a relative value in the SVG space, e.g. 10
  • an absolute or relative measurement, e.g. 10px. SVG supports em, ex, px, pt, pc, cm, mm, in and percentage units.

If your image will be scaled, use units which are relative to your viewbox, e.g. a line width of 10 within a 100×100 viewbox will be 10% of the full width/height.

SVG XML Document

An SVG image is defined as an XML document. Assuming you’re creating a new SVG file, such as image.svg, an XML declaration and doctype must appear at the top of the document:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

This is followed by the root SVG element:


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

Several optional attributes can be applied to the svg element. Two important ones are:

  • viewBox: establish the dimensions — a rectangular co-ordinate area used for your image specified as “min-X min-Y width and height”, e.g. viewBox="0 0 600 400". It’s important to remember this is an abstract space; it does not relate to pixels and your drawing elements are not constrained within these co-ordinates.
  • preserveAspectRatio: defines how a viewbox is scaled. There are many options, for example preserveAspectRatio="xMidYMid meet" ensures the middle of an SVG’s viewbox is aligned with the middle of the viewport (the browser window or HTML element containing the SVG) and the image fits the space available while preserving its aspect ratio.

An optional title and description can be defined using title and desc elements. Our basic XML document is therefore:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" preserveAspectRatio="xMidYMid meet">
	<title>My First Scalable Vector Graphic</title>
	<desc>An experimental SVG from SitePoint.com</desc>

	<!-- drawing elements to go here -->

</svg>

Grouping Elements

Any set of elements (lines, circles, rectangles, text, etc.) can be grouped using <g> … </g> tags. In essence, it’s identical to grouping drawing objects in a graphics package so they can be manipulated as a single item.

Personally, I prefer to define a root group node so I can modify the whole image easily via JavaScript or CSS, e.g.


<g id="main">
	<!-- drawing elements to go here -->
</g>

A single group can have any number of nested inner groups.

Lines

A single line between two points is drawn using the line element:


<line x1="10" y1="10" x2="100" y2="200" 
stroke="#999" stroke-width="5" stroke-linecap="round" />

The stroke-linecap attribute defines the line-end effect and accepts values of butt (the default), round, square or inherit:

SVG stroke-linecap

Polylines

Polylines define a set of connected straight line segments:


<polyline points="580,10 560,390 540,200 520,390 400,390" 
stroke="#c00" stroke-width="5" stroke-linecap="round" 
stroke-linejoin="round" fill="none" />

The stroke-linejoin attribute defines the line-joining effect and accepts values of miter (the default), round, bevel or inherit:

SVG stroke-linejoin

Polygons

Polygons are are similar to polylines except that the resulting shape will always be closed:


<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" 
stroke="#ff0" stroke-width="10" fill="#ff6" />

Rectangles

Square or rounded rectangles are defined using the rect element:


<rect x="100" y="10" width="150" height="100" rx="10" ry="20" 
stroke="#060" stroke-width="8" fill="#0f0" />

The x and y attributes define the top-left corner. rx and ry specify the horizontal and vertical corner rounding.

Circles

Circles are defined using a center point and radius:


<circle cx="100" cy="300" r="80" 
stroke="#909" stroke-width="10" fill="#f6f" />

Ellipses

Ellipses are defined using a center point and two radii values:


<ellipse cx="450" cy="50" rx="80" ry="30" 
stroke="#0cc" stroke-width="10" fill="#0ff" />

Text

Basic text can be added using the text element:


<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>

The x and y attributes define the bottom-left co-ordinate of the first character in the string.

The Result

Our final SVG document contains the following XML code:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" preserveAspectRatio="xMidYMid meet">
	<title>My First Scalable Vector Graphic</title>
	<desc>An experimental SVG from SitePoint.com</desc>
	<g id="main">
		<line x1="10" y1="10" x2="100" y2="200" stroke="#00c" stroke-width="5" stroke-linecap="round" />
		
		<polyline points="580,10 560,390 540,200 520,390 400,390" stroke="#c00" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
		
		<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="#ff0" stroke-width="10" fill="#ffc" />
		
		<rect x="100" y="10" width="150" height="100" rx="10" ry="20" stroke="#060" stroke-width="8" fill="#0f0" />
		
		<circle cx="100" cy="300" r="80" stroke="#909" stroke-width="10" fill="#f6f" />
		
		<ellipse cx="450" cy="50" rx="80" ry="30" stroke="#0cc" stroke-width="10" fill="#0ff" />
		
		<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>
	</g>
</svg>

and renders this image:


SVG example

click to view the actual SVG

While this is a simple example, the file is 1,176 bytes before minification and gzipping. The equivalent compressed PNG above is 5,611 bytes — it’s almost 5x larger and cannot be scaled above its native 407×274 resolution without losing quality.

Further Scalable Vector Graphic articles will appear on SitePoint soon…

Login or Create Account to Comment
Login Create Account
Recommended
Sponsors
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?