Captain America's Shield

Cet article est également disponible en français

While most designers use a visual editor like to create 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 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