svg

Why not make your own SVG icons?

Here are some SVG icons:

What these icons have in common is that they are incredibly easy to make yourself!

In fact, they are so easy to make that I will just put their code here, and I am confident you will understand it without any additional information.

<svg width="40" height="40" viewBox="0 0 10 10">
  <line x1="1" y1="2" x2="9" y2="2" stroke="goldenrod" stroke-linecap="round" />
  <line x1="1" y1="5" x2="9" y2="5" stroke="goldenrod" stroke-linecap="round" />
  <line x1="1" y1="8" x2="9" y2="8" stroke="goldenrod" stroke-linecap="round" />
</svg>

<svg width="40" height="40" viewBox="0 0 12 12">
  <circle cx="6" cy="6" r="5" stroke="goldenrod" fill="none" />
  <line x1="4" y1="6" x2="8" y2="6" stroke="goldenrod" stroke-linecap="round"/>
  <line x1="6" y1="4" x2="6" y2="8" stroke="goldenrod" stroke-linecap="round"/>
</svg>

<svg width=40 height=40 viewBox="0 0 10 10">
  <circle cx="5" cy="4" r="2" stroke="goldenrod" fill="none" />
  <rect x="2" y="4" width="6" height="4" rx="1" fill="goldenrod" />
</svg>

ViewBox

One thing that might be slightly confusing is the viewBox.

The viewBox defines the raster on which the elements of the SVG will be placed.

The four numbers represent the origin coordinate's X and Y values (often 0 0) and the width and height of the raster.

A viewBox of 0 0 10 10 will generate a raster with origin coordinates (0, 0), 10 columns (width) and 10 rows (height).

0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10

Within this viewBox you can define the components that make up your SVG.

<svg width="40" height="40" viewBox="0 0 10 10">
  <line x1="1" y1="5" x2="4" y2="3" stroke="goldenrod" stroke-linecap="round" />
  <line x1="1" y1="5" x2="9" y2="5" stroke="goldenrod" stroke-linecap="round" />
  <line x1="1" y1="5" x2="4" y2="7" stroke="goldenrod" stroke-linecap="round" />
</svg>
0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10 (1, 5) (4, 3) (4, 7) (9, 5)

The viewBox is only used to define the position of the components on the raster. In our example the lines are positioned on a 10 by 10 raster but are scaled to a 40px by 40px icon due to the width and height values of the SVG.

Edge values

You might have noticed that all icon definitions stay at least 1 viewBox unit away from the edge of the viewBox.

This is because strokes are centered around their path. A horizontal line with Y = 5 will be drawn from half a unit above the Y5 line to half a unit below the Y5 line. A line on the Y0 line will therefor lose half of its width (due to the top half being cut off).

Also, the stroke-linecap (the rounded endings of the line) are drawn half a unit past the line's endpoints.

<svg viewBox="0 0 10 10">
  <line x1="1" y1="0" x2="9" y2="0" stroke="goldenrod" stroke-linecap="round" />
  <line x1="0" y1="2" x2="8" y2="2" stroke="goldenrod" stroke-linecap="round" />
  <line x1="1" y1="4" x2="9" y2="4" stroke="goldenrod" stroke-linecap="round" />
</svg>
0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5

Groups

If you notice you are repeating the same attributes (e.g.: fill, stroke, stroke-linecap) over and over again in your elements, it might be time to start grouping them together.

This can be achieved by wrapping the elements with a <g> element.

(i) Groups can also be used when animating or styling an SVG by targeting the grouped parts by their group's id.

Some of the initial examples can be defined as follows (notice the added <g> element):

<svg width="40" height="40" viewBox="0 0 10 10">
  <g stroke="goldenrod" stroke-linecap="round">
    <line x1="1" y1="2" x2="9" y2="2" />
    <line x1="1" y1="5" x2="9" y2="5" />
    <line x1="1" y1="8" x2="9" y2="8" />
  </g>
</svg>

<svg width="40" height="40" viewBox="0 0 12 12">
  <g stroke="goldenrod" stroke-linecap="round">
    <circle cx="6" cy="6" r="5" fill="none" />
    <line x1="4" y1="6" x2="8" y2="6" />
    <line x1="6" y1="4" x2="6" y2="8" />
  </g>
</svg>

(i) In our simple examples all elements share the same group. In such cases you can define the shared attributes on the <svg> element itself instead of adding a group.

<svg width="40" height="40" viewBox="0 0 10 10" stroke="goldenrod" stroke-linecap="round">
  <line x1="1" y1="2" x2="9" y2="2" />
  <line x1="1" y1="5" x2="9" y2="5" />
  <line x1="1" y1="8" x2="9" y2="8" />
</svg>

Paths

If you are worried about the size of the SVG element in the HTML file, you can use a path element which uses an encoding to define lines, arcs, and curves.

Certain animations can also require you to use a path instead of separate lines, circles, or rectangles.

You can learn more about the SVG path element in this MDN tutorial.

<svg width="40" height="40" viewBox="0 0 10 10">
  <path d="M1 2h8M1 5h8M1 8h8" stroke="goldenrod" stroke-linecap="round" />
</svg>

<svg width="40" height="40" viewBox="0 0 12 12">
  <path d="M6 1A5 5 1 0 0 6 11M6 1A5 5 0 0 1 6 11M4 6h4M6 4v4" stroke="goldenrod" stroke-linecap="round" fill="none" />
</svg>

Since you cannot draw complete circles with the arc syntax, we draw 2 semicircles instead.

Q & A

Q: Where is the XML namespace (xmlns="http://www.w3.org/2000/svg")?

A: When using SVG elements in an HTML5 context you do not need to specify the namespace.


Q: Why are all icons defined as squares?

A: This is personal preference. It preserves the width and height of the SVG element when rotating the icon (at least when rotating by steps of 90 degrees).

vs