While most designers use a visual editor like Adobe Illustrator to create SVG drawings, knowing the basics of SVG syntax can allow you to create elements like lines, circles and rectangles easier and more precisely; in some cases, coding these elements by hand produces work faster than a visual editor ever could.
Circles
Let’s look at a basic SVG drawing of a circle; to keep things simple, I’ll leave the possible complications of user units and other variations for another article.
You could write this code inside the <body>
of an HTML page, or as it’s own document, saved with a .svg extension; either way, the result will be viewable in a browser.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<circle cx="100" cy="100" r="80" fill="red" />
</svg>
Which results in:
There’s a few things to note immediately:
- The
circle
element must be “closed inside itself” with a closing slash (/
) - The circle is positioned from its center (
cx
for “center, x-axis”,cy
for “center, y axis”). - The center of the circle is measured from the top left corner of the SVG element.
- The radius (
r
) of the circle is, by default, measured in the same units as everything else. - If any of these attributes are not defined, they are assumed to be 0 (and for presentational attributes involving color, black).
- The fill of the circle can be specified using any CSS color system you like.
Like rectangles and other SVG elements, an SVG circle has two “parts”: an interior fill and an external stroke.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<circle cx="100" cy="100" r="80" fill="red" stroke-width="15" stroke="black" />
</svg>
The code for the circle is getting a little long and complicated; let’s clean it up with a class selector:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="80" class="redcirc" />
</svg>
And use this CSS:
svg {
width: 200px; height: 200px;
}
.redcirc {
fill: red;
stroke: black;
stroke-width: 15;
}
The result is the same as the previous version:
Once we have that, it’s very easy to start creating more complex drawings. I think you can see where we’re going here:
<svg viewBox="0 0 500 500">
<title>Captain America's Shield</title>
<circle cx="250" cy="250" r="250" fill="red" />
<circle cx="250" cy="250" r="200" fill="white" />
<circle cx="250" cy="250" r="150" fill="red" />
<circle cx="250" cy="250" r="100" fill="blue" />
<polygon fill="white" points="250,150 280,209 346,219 298,265 309,330 250,300 192,330 203,265 155,219 221,209" />
</svg>
Note that SVG elements layer just like HTML elements.
An Alternative Shield
We can be cleverer than this: as a general rule, the fewer elements in an SVG document, the better, so we can fake sections of the shield by using stroke
and just two circles:
<svg viewBox="0 0 500 500">
<title>Captain America's Shield</title>
<circle cx="250" cy="250" r="220" fill="white" />
<circle cx="250" cy="250" r="125" fill="blue" />
<polygon fill="white" points="250,150 280,209 346,219 298,265 309,330 250,300 192,330 203,265 155,219 221,209" />
</svg>
Combined with this CSS:
circle {
stroke-width: 50;
stroke: red;
}
The result is the same as the original; the full version also uses an interesting variation of flexbox and box-shadow
to position and shadow the shield.
Ellipses
The syntax for ellipses is very similar to circles:
<svg viewPort="0 0 120 120">
<ellipse cx="60" cy="60" rx="60" ry="30" />
</svg>
In this case, there are two radius measurements, representing the semi-major and semi-minor axes of the ellipse.
One useful feature of circles and ellipses (and SVG shapes in general) written inline on a page is that, unlike HTML elements, their “hit area” exactly matches their actual shape. So if we link an ellipse:
<svg viewPort="0 0 120 120">
<a xlink:href="http://www.cnn.com">
<ellipse cx="60" cy="60" rx="50" ry="25" />
</a>
</svg>
And combine it with this CSS:
ellipse:hover { fill: red; }
The result is what you see below: note the very precise response to mouse position, especially coming in from the “corners”.
It’s possible to replicate this in HTML with border-radius
on a
elements, but the challenge becomes insurmountable the moment button shapes become more complicated, one reason why SVG makes a great format for UI elements.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/ZGOKLJ