SVG 101 for Programmers

This article is part of my web development series 'webDEV101'. You can read the whole series here:

SVG?
SVG, or Scalable Vector Graphics, is a graphics format based on XML. Unlike Raster image formats such as PNG and JPG, SVG code is human-readable.
LetComparison x64 PNG encoding and SVG code for a simple circle with a black rim, a white ring, and a red filling:

PNG Base 64 encoding:
iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABGElEQVR42u3SwQ3CQBBA0QOhCChEBEAwURBkgIRQAQioEACFSBBjBFHBp8x6p87ffTh1CVVVVVVVVVVVVVVVVVVdWllDziR/3hFX60WvvMWvTX7xFr3/D3X0EAAAD//3S2j3gAAAAASUVORK5CYII...
SVG code:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
Therefore, you can program SVG files just like you could program HTML files to create stunning vector graphics:
(IMAGE)
Should I learn SVG?
SVG is a powerful image format.
SVG is universal. It is supported as HTML 5 in virtually all browsers, including but not limited to Firefox and the bazellion Chromium ones (Chrome, Edge, Vivaldi, etc.), although loading can be slow.
SVG is also much more suitable than raster image formats for computer illustration. Since all graphics are specified geometrically instead of by pixels, SVGs can zoom in and out without losing resolution.
However, many web developers do not learn SVG. SVG is like the image equivalent of LaTex. Most people write, but few learn LaTex. Most people view graphics, many create graphics, but few learn SVG. There are many visual SVG editors, such as the open-source Inkscape, or the quintessentially Adobe Illustrator. WYSIWYG is the overwhelmingly dominant approach to SVG, partly because there are certain complexities in creating curves programmatically.
So, is SVG for you?
SVG is not for you unless you create your own graphics. There are so many SVG libraries online nowadays, after all. Why not just lift one off the shelf and use it in your work?
SVG is not for you if you prefer WYSIWYG (What You See Is What You Get) like most people. HTML and CSS are enough complexities, and there is nothing wrong with taking a purely visual approach to creating something visual.
SVG is for you, if you are like me, interested in math, and curious about the underlying geometrical pattern in images. When I was an angsty 15-year-old taking CS 10-1, we spent an entire semester learning Processing, a variant of Java designed for visual artists. We created all kinds of images and animations, ranging from outright silly to credibly stunning. Learning Processing was one of the few happy episodes of my otherwise tumultuous teenage years. Learning SVG is bringing me back the joy. SVG can achieve most of the things I did in Processing and output it in a universally portable format. It is also much more efficient and organised than Processing for static images.

SVG is for you if you, like me, love to do things programmatically. I do things programmatically whenever practical. I write Markdown in VScode instead of using a text editor, run Ronzz.org over Ghost instead of a Wix-like click-and-drag web building and hosting service, and manage my files with the terminal instead of a GUI file explorer.
Programmatical approaches are much more precise. While art may favour spontaneity and impression, technical illustrations are better off exact:


WYSIWYG vs. SVG
Using SVG over drag-and-click graphics editors makes your diagrams much more professional.
Setup
SVG is visual. Especially when starting out, having live previews to see your changes reflected in real time would be immensely helpful. If you already have a code editor, you can usually install an extension, such as SVG by Jock and use the built-in text editor. If not, you can use an online editor, such as the online version of GodSVG (quite a strong name, I give it).
The Basics
Familiarity with a Markup language, such as HTML, will help. You can find a short guide on HTML here:

Follow the guide until Organization, which should take less than 30 minutes, is sufficient to achieve a basic familiarity with a Markup language.
Assuming basic familiarity with Markup language, SVG is very intuitive. Let's start with a simple example:
<svg version="1.1"
width="300" height="300"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#7ef652" />
<circle cx="150" cy="150" r="80" fill="#db3eb7" />
<text x="150" y="150" font-size="45" text-anchor="middle" fill="white">SVG</text>
</svg>

Tags
All SVG files should be enclosed in a pair of <svg></svg>
tags. The opening tag should have attributes version
and xmlns
(XML namespace) to ensure the correct recognition and rendering of graphics by browsers and other XML processors. The width
and height
attributes specify the canvas size.
Simple elements are declared with the syntax <element_name attributeA="value" attributeB="value"... />
or<element_name attributeA="value" attributeB="value"... >Content</element_name>
. This is identical to HTML, except that self-closing elements end with />
instead of >
.
Attributes: coordinates and colours in particular
Many attributes, such as width
and font-size
, are self-explanatory. x
and y
refers to spatial coordinates on the canvas. cx
and cy
stands for centre x and centre y.
(ILLUSTRATION coordinate system in SVG, in SVG)
Colours, such as fill
, can be specified in standard HEXcode or HEXcode with transparency (RGBA).
Order of rendering
The direction of rendering in SVG is from up to down. Elements at the top will be drawn first and covered by elements below, similar to a human drawer following a series of instructions.

HTML integration
SVG can be directly embedded in HTML as an HTML tag. However, since large SVGs can be slow to load, it may be preferable to embed them as an image object.
<object data="example.svg" type="image/svg+xml"></object>
Viewbox
It is possible to zoom in and focus on a particular section of an SVG:
If we add the attribute viewBox="0 0 100 100"
to the header line of our simple example:
<svg version="1.1"
width="300" height="300"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">

The viewport will display the rectangular section enclosed by (0,0), (0,100), (100,0) and (100,100) on the original 300 x 300 canvas, effectively zooming in 300%.
Note most browsers do not automatically supply scroll bars, so users simply cannot see the other sections. The viewBox
attribute is useful for displaying different visual effects without modifying the content of the SVG. You can create a very large SVG illustration, a whole comic series if you will, and then use the viewBox
attribute to display specific frames (sections).
The Shapes
Very basic ones
Rectangles:
<rect x="60" y="10" rx="10" ry="10" />
Ellipses:
<ellipse cx="75" cy="75" rx="20" ry="5" />
Polylines:
<polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 14" />
Text:
<text x="150" y="150" font-size="45" text-anchor="middle" fill="white">SVG</text>
Circles:
<circle cx="75" cy="75" r="20" />
Polygons:
<polygon points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 14" />
The circle is simply a special case of ellipse where rx=ry
, and the polygon is just a polyline with the first vertex repeated at the end.
Fancy ones: Path
The path is the most general shape in SVG. It can be used to draw everything, including basic shapes and fancy curves.
Linear path
<path d="M 10 10 H 90 V 90 h -80 v -80 L 90 90 Z" stroke="#aaaaaa" />

Path trajectories are specified by the d
attribute.
The d
attributes take a series of single-letter commands with the general format action coordinate(s)
, and behaves pretty much like Turtle
in Python, that is, a tracer drawing over the canvas.

For vivacity, we will call this tracer Mx. Turtle.
M x y
instructs Mx. Turtle to take out the invisibility cloak and move to (x,y)
without leaving any trace behind. For instance, d="M 10 10 M 20 20"
causes Mx. Turtle to move from (10,10) to (20,20), without drawing anything.
L x y
on the other hand, tells Mx. Turtle to move and leave a trace behind. For instance, d="M 10 10 L 20 20"
causes Mx. Turtle to move from (10,10) to (20,20) and draw a line segment between (10,10) and (20,20) as he moves.
V
and H
are special cases of L
, where only the horizontal or vertical coordinate changes, so the other coordinate is omitted for simplicity.
Z
pats Mx. Turtle on the back and sends them to sleep: 'Kudos! Job done!'
For each capital letter command M L V Z
that takes absolute coordinates, there is also a lower-case correspondent m l v z
that takes relative coordinates to the position of Mx. Turtle. For instance, while L 20 20
tells Mx. Turtle to draw a line from their current position (x,y)
to (20,20)
, l 20 20
tells Mx. Turtle to draw a line from the current position (x,y)
to(x+20,y+20)
.
Note for English learners: 'they' is the gender-neutral pronoun in contemporary English. It does not suggest plurality. -Ron
Curve paths:
If Mx. Turtle can only draw linear paths, then we would not really need them: Polyline will do, albeit slightly more inconvenient, perhaps. The true prowess of Mx. Turtle is in their ability to do curves.
Cubic curves:
<path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>

General form:
<path d="M x y C x1 y1, x2 y2, x3 y3" />
The curve is drawn from the current position (x,y)
to endpoint (x3,y3)
, with (x1,y1)
and (x2,y2)
as control points:

<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="white"/>
<!-- Grid lines -->
<g stroke="lightgray" stroke-width="0.5">
<!-- Horizontal lines -->
<line x1="0" y1="10" x2="190" y2="10"/>
<line x1="0" y1="20" x2="190" y2="20"/>
<line x1="0" y1="30" x2="190" y2="30"/>
<line x1="0" y1="40" x2="190" y2="40"/>
<line x1="0" y1="50" x2="190" y2="50"/>
<line x1="0" y1="60" x2="190" y2="60"/>
<line x1="0" y1="70" x2="190" y2="70"/>
<line x1="0" y1="80" x2="190" y2="80"/>
<line x1="0" y1="90" x2="190" y2="90"/>
<line x1="0" y1="100" x2="190" y2="100"/>
<line x1="0" y1="110" x2="190" y2="110"/>
<line x1="0" y1="120" x2="190" y2="120"/>
<line x1="0" y1="130" x2="190" y2="130"/>
<line x1="0" y1="140" x2="190" y2="140"/>
<line x1="0" y1="150" x2="190" y2="150"/>
<!-- Vertical lines -->
<line x1="10" y1="0" x2="10" y2="160"/>
<line x1="20" y1="0" x2="20" y2="160"/>
<line x1="30" y1="0" x2="30" y2="160"/>
<line x1="40" y1="0" x2="40" y2="160"/>
<line x1="50" y1="0" x2="50" y2="160"/>
<line x1="60" y1="0" x2="60" y2="160"/>
<line x1="70" y1="0" x2="70" y2="160"/>
<line x1="80" y1="0" x2="80" y2="160"/>
<line x1="90" y1="0" x2="90" y2="160"/>
<line x1="100" y1="0" x2="100" y2="160"/>
<line x1="110" y1="0" x2="110" y2="160"/>
<line x1="120" y1="0" x2="120" y2="160"/>
<line x1="130" y1="0" x2="130" y2="160"/>
<line x1="140" y1="0" x2="140" y2="160"/>
<line x1="150" y1="0" x2="150" y2="160"/>
<line x1="160" y1="0" x2="160" y2="160"/>
<line x1="170" y1="0" x2="170" y2="160"/>
<line x1="180" y1="0" x2="180" y2="160"/>
</g>
<!-- Cubic Curves -->
<path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>
<path d="M 70 10 C 70 20, 110 20, 110 10" stroke="#f66666" fill="transparent"/>
<path d="M 130 10 C 120 20, 180 20, 170 10" stroke="#0af460" fill="transparent"/>
<path d="M 10 60 C 20 80, 40 80, 50 60" stroke="black" fill="transparent"/>
<path d="M 70 60 C 70 80, 110 80, 110 60" stroke="#f66666" fill="transparent"/>
<path d="M 130 60 C 120 80, 180 80, 170 60" stroke="#0af460" fill="transparent"/>
<path d="M 10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/>
<path d="M 70 110 C 70 140, 110 140, 110 110" stroke="#f66666" fill="transparent"/>
<path d="M 130 110 C 120 140, 180 140, 170 110" stroke="#0af460" fill="transparent"/>
</svg>
Notice that there is no support for any loops in SVG. So unfortunately, to draw the grid lines, I had to repeat the line command 33 times (Of course, that was Github Copilot taking the grind).

An intuition on control points: The slopes of the Bézier curve and the line joining control points are equal at the intersection.
Curves are best mastered by experimenting around yourself. Open a code editor and set up a live-preview. Tweak around the parameters to see what changes. -Ron
Quadratic Bézier curve:
<path d="M x y Q x1 y1, x3 y3" />
The quadratic Bézier curve is a special case of the cubic Bézier curve in which the two control points (x1,y1) and (x2,y2)
overlap.

Arcs
Arcs is the most complex path in SVG.
The general form is:
<path d='M x y A rx ry x-axis-rotation binary: large-arc-flag binary:sweep-flag x1 y1'>
<path d='M x y a rx ry x-axis-rotation binary:large-arc-flag binary:sweep-flag dx dy'>
An example:
<path d="M 10 10 a 20 25 15 0 1 20 20" fill="none" stroke="#7b0f0f">
Binary flags
: An arc is a part of an ellipse. There are two possible ellipses of radius rx
, ry
crossing points (x,y)
and (x1,y1)
:
On each ellipse, there are two possible arcs: major and minor.
Therefore, the binary flags (1 or 0) are important to render deterministically.
Remarks
If you followed this tutorial, you should now be familiar with SVG syntax and basic methods. To learn more, consider reading the MDN web docs. GitHub Copilot can also answer specific questions you may have on SVG!
Copyright Statement
Énoncé du droit d'auteur

Much of our content is freely available under the Creative Commons BY-NC-ND 4.0 licence, which allows free distribution and republishing of our content for non-commercial purposes, as long as Ronzz.org is appropriately credited and the content is not being modified materially to express a different meaning than it is originally intended for. It must be noted that some images on Ronzz.org are the intellectual property of third parties. Our permission to use those images may not cover your reproduction. This does not affect your statutory rights.
Nous mettons la plupart de nos contenus disponibles gratuitement sous la licence Creative Commons By-NC-ND 4.0, qui permet une distribution et une republication gratuites de notre contenu à des fins non commerciales, tant que Ronzz.org est correctement crédité et que le contenu n'est pas modifié matériellement pour exprimer un sens différent que prévu à l'origine.Il faut noter que certaines images sur Ronzz.org sont des propriétés intellectuelles de tiers. Notre autorisation d'utiliser ces images peut ne pas couvrir votre reproduction. Cela n'affecte pas vos droits statutaires.
Member discussion