SVG quest
I have a tendency, a preference for writing SVG “by hand”, in a code editor rather than a graphics program. The process might seem tedious and laborious, but I often can’t help myself. There’s so much to appreciate in the syntax, even from the combination of a few elements and attributes. Case in point, consider the following entries modeled after a block-sized mobile video game.
By the end of this article, you’ll have drawn both sprites yourself and you’ll be free to experiment with other entries as well. There are bound to be more in the collection.
Starting with the first, electrifying presence set up a large canvas. An empty <svg> element and a convenient, square viewBox. You can even add a <title> element to explain the figure.
<svg viewBox="0 0 100 100">
<title>Magnemite</title>
</svg> To draw the sprite we can just use one shape over and over, a humble <rect>angle.
One large square for the base, with the rx attribute to round the corners.
<rect fill="hsl(195 36% 78%)" width="100" height="100" rx="8" /> Two additional squares for the eye. A bright one to introduce the socket, a dark one to detail the pupil.
<rect fill="hsl(216 45% 98%)" x="25" y="12" width="50" height="50" />
<rect fill="hsl(300 1% 37%)" x="47" y="33.5" width="6" height="6" /> The size of the shapes is not as important as their position. Horizontally, you want to center the squares in the larger container. Vertically, you want to separate the pieces enough to create a distinct unit. There is no right number in this sense, which makes the choice both frustrating and freeing. Pick a number, and change the value until it looks right to you, to your sharp eyes.
For the small knobs we can repeat the process, but there are ways to simplify the sequence. Consider a knob as an independent piece. A square for the base.
<rect fill="hsl(300 2% 79%)" width="20" height="20" /> Two additional rectangles of different sizes, positioned to create a small plus sign smack in the center.
<rect fill="hsl(0 1% 55%)" x="7" y="2" width="6" height="16" />
<rect fill="hsl(0 1% 55%)" x="2" y="7" width="16" height="6" /> The two have the same color, the same fill, so you can gather the lot in a common group element with the shared attribute.
<g fill="hsl(0 1% 55%)">
<!-- ...rects -->
</g> Alone, the code is enough to draw one knob. In the larger canvas, however, we want to place the shapes at specific x, y coordinates. Twice. For this we can use additional group elements and the transform attribute, literally translating the figures.
<g transform="translate(8 68)">
<!-- ...rects -->
</g>
<g transform="translate(72 68)">
<!-- ...rects -->
</g> Again, the numbers are a mix of logic and your better judgment. You want the knobs separate from the eye, but horizontally in perfect symmetry. As you decide the position of the first piece, 8 from the left, the other one follows with a bit of math. 8 from the right, 100 minus 8 minus the width of the larger rectangle. You even get to practice with basic arithmetic.
And that’s it. The rectangles stack up to create the first entry.
It is remarkable how little it takes to complete the drawing. And it is even more impressive how the syntax evolves for the second sprite.
From the top, one canvas-ready <svg> element with a proper label.
<svg viewBox="0 0 100 100">
<title>Magneton</title>
</svg> One soft rectangle as a base.
<rect fill="hsl(195 36% 78%)" width="100" height="100" rx="8" /> To fill the canvas you can certainly continue with <rect> elements. You can set the positions and the dimensions with a calculator by your side, but gladly, you don’t have to. You want to repeat the first sprite three times, and for this, SVG offers the <symbol> element.
One symbol with a unique id.
<symbol id="magnemite">
<!-- ... -->
</symbol> One symbol with the familiar viewBox and the same instructions you took the time to elaborate in the first drawing.
<symbol id="magnemite" viewBox="0 0 100 100">
<!-- ...rects -->
</symbol> You are essentially taking the first <svg> and renaming the element. In this manner you have a graphic you can then use with <use> element.
<use href="#magnemite" /> Use and re-use in different spots with the x and y attributes. Use and re-use in different sizes with width and height.
<use href="#magnemite" x="25" width="50" height="50" />
<use href="#magnemite" y="50" width="50" height="50" />
<use href="#magnemite" x="50" y="50" width="50" height="50" /> And that’s close to it. The code works to place the copies — you do find the trio in a short pyramid — but with one visual bug.
At fault, the precious rx attribute we used for the base. We don’t want a gap between the copies, so that the most immediate solution is to just remove the value.
-<rect fill="hsl(195 36% 78%)" width="100" height="100" rx="8" />
+<rect fill="hsl(195 36% 78%)" width="100" height="100" /> But at the risk of sounding philosophical, the change begs a question, how should we round the rectangle for individual <svg> elements? The rectangle describing the base?
If you remove the attribute from all shapes, you have a few options. You can round the corners with CSS and the border-radius property.
svg {
border-radius: 8%;
} Sticking with SVG, you can clip the visible area with a <clipPath> element. The solution is more involved, but feels most appropriate as you explore the syntax. And the good news is that, eventually, you do get to keep the rx attribute.
One <clipPath> element with a unique id. You might be used to the practice.
<clipPath id="clip-entry">
<!-- ... -->
</clipPath> One clip describing the visible area with the largest, 100 by 100, rounded rectangle.
<clipPath id="clip-entry">
<rect width="100" height="100" rx="8" />
</clipPath> The moment you apply the clip with the clip-path attribute, on the individual entry you find the same exact result.
<g clip-path="url(#clip-entry)">
<rect fill="hsl(195 36% 78%)" width="100" height="100" />
<!-- ...rects -->
</g> And on the larger composition, repeating the sharp shapes, you get the final picture.
<g clip-path="url(#clip-entry)">
<rect fill="hsl(44 100% 68%)" width="100" height="100" />
<!-- ...uses -->
</g> This time, the entry is truly complete.
And I do hope the <clipPath> element didn’t discourage you from the overarching plot.
Writing SVG yourself is not complicated. Elementary shapes are more than enough to craft beautiful, custom drawings. And if the process inspired you there might be another triplet in the same video game. You’ll certainly be able to recreate the visuals without editing software. And truth being told, the entire catalog is up for grabs with time and patience. You might even explore more elements, like the flexible <path>, to continue the rewarding journey.