web3icons

SVG paths explained: M, L, C, A and Z

How to read the d attribute of an SVG path, from simple lines to curves and arcs, and why paths exported from design tools look so dense.

6 min read

Almost every logo in an icon set is made of <path> elements, and the whole shape lives in one attribute, d. It looks like noise (M12 2a10 10 0 1 0 0 20...), but it is a list of drawing commands: a letter followed by numbers. Learn ten letters and you can read any icon, spot a broken export, or make a small fix by hand.

The commands at a glance

Command Name Parameters Draws
M moveto x y Nothing; lifts the pen and starts a new subpath
L lineto x y Straight line
H horizontal lineto x Horizontal line
V vertical lineto y Vertical line
C curveto x1 y1 x2 y2 x y Cubic Bézier curve
S smooth curveto x2 y2 x y Cubic curve continuing the previous one
Q quadratic curveto x1 y1 x y Quadratic Bézier curve
T smooth quadratic x y Quadratic curve continuing the previous one
A arc rx ry rotation large-arc sweep x y Elliptical arc
Z closepath none Straight line back to the subpath's start

The coordinates are in the units of the file's viewBox. In a 0 0 24 24 icon, 12 12 is the center.

Straight lines with M, L, H, V and Z

Start with a diamond, the kind of shape many token marks are built from:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M 12 2 L 19 12 L 12 22 L 5 12 Z" fill="#9ca3af"/>
</svg>

Read it as a pen: move to the top point (12, 2), draw lines to the right (19, 12), bottom (12, 22) and left (5, 12) corners, and Z closes back to the top.

H and V are shortcuts for lines that only change one coordinate. A 16 × 8 rectangle starting at (4, 8):

<path d="M4 8 H20 V16 H4 Z"/>

Without Z the shape is still filled, but a stroke would skip the final edge back to the start.

Uppercase is absolute, lowercase is relative

Every command has two forms. Uppercase coordinates are absolute positions on the grid. Lowercase coordinates are offsets from wherever the pen currently is.

Here is the same diamond written both ways:

<path d="M12 2 L19 12 L12 22 L5 12 Z"/>
<path d="M12 2 l7 10 -7 10 -7 -10 z"/>

In the second line, l7 10 means "7 right and 10 down from here", which lands on (19, 12). Notice also that the l appears only once. When numbers keep coming after a command, the command repeats. After a moveto, extra pairs are treated as linetos, so M12 2 19 12 12 22 5 12z draws the same diamond again.

Optimized files favor relative commands because smaller numbers take fewer characters.

Curves with C and S

A cubic Bézier curve has a start point (where the pen is), two control points and an end point. The control points pull the curve toward them without the curve passing through them.

<path d="M4 16 C 8 4, 16 4, 20 16" fill="none" stroke="#9ca3af" stroke-width="2"/>

This draws an arch from (4, 16) to (20, 16). The first control point (8, 4) sets the direction the curve leaves the start; the second (16, 4) sets how it arrives at the end. Commas are optional separators.

S continues a curve smoothly. It takes only the second control point and the end point; the first control point is the mirror image of the previous curve's second control point. That is how a smooth S-bend or a whole circle gets written with fewer numbers.

Q and T are the quadratic versions, with one control point instead of two. They are less common in icon files.

Arcs with A

Arcs draw part of an ellipse and take seven numbers, in this order: A rx ry x-axis-rotation large-arc-flag sweep-flag x y.

  • rx ry: the radii. For circles they are equal.
  • x-axis-rotation: tilts the ellipse, in degrees. Usually 0.
  • large-arc-flag: between two points there is a short arc and a long one. 1 picks the long one.
  • sweep-flag: 1 draws in the positive-angle direction, which looks clockwise on screen because the y axis points down. 0 goes the other way.
  • x y: the end point.

A full circle cannot be one arc, because an arc whose start and end are the same point draws nothing. So circles in path form are two half-circle arcs:

<path d="M12 2 A10 10 0 1 0 12 22 A10 10 0 1 0 12 2 Z"/>

Start at the top, sweep counterclockwise to the bottom, then continue around to the top. If the radii are too small to reach the end point, the browser scales them up until they fit, so slightly rounded radii still render.

Reading a real icon path

Here is a complete, compact icon: a filled circle with a plus cut out of it, as you might use for an "add token" button.

<path d="M12 2a10 10 0 1 0 0 20 10 10 0 1 0 0-20zm-1 5h2v4h4v2h-4v4h-2v-4H7v-2h4z"/>

Taking it apart:

Segment Meaning Pen ends at
M12 2 Start at the top of the circle (12, 2)
a10 10 0 1 0 0 20 Half circle, counterclockwise, 20 units down (12, 22)
10 10 0 1 0 0-20 Implicit second arc, back up 20 (12, 2)
z Close the circle (12, 2)
m-1 5 New subpath, 1 left and 5 down from the start (11, 7)
h2 v4 h4 v2 h-4 v4 h-2 v-4 Trace around the top, right and bottom arms (11, 13)
H7 v-2 h4 z Left arm, then close (11, 7)

Note that 0-20 is two numbers, 0 and -20, because a minus sign starts a new number. Also, the plus is traced clockwise while the circle runs counterclockwise. That opposite direction is what makes the plus a hole under the default fill rule, explained in fill-rule: nonzero vs evenodd.

Why design tool output looks the way it does

Paths exported from design tools, and especially files run through an optimizer, look denser than hand-written ones. The usual reasons:

  • Everything becomes a path. Rectangles, circles and text are converted to outlines so they render the same everywhere.
  • Circles become curves. Many tools write a circle as four cubic curves instead of two arcs, for example M12 2C17.52 2 22 6.48 22 12S17.52 22 12 22 2 17.52 2 12 6.48 2 12 2z. Four curves approximate a circle closely enough that nobody can see the difference.
  • Compressed number syntax. Leading zeros are dropped (.5 instead of 0.5), and separators vanish where a sign or decimal point already separates numbers. 1.5.5 is the two numbers 1.5 and 0.5. Some optimizers also drop the spaces between arc flags.
  • Floating-point leftovers. Flattening transforms produces coordinates like 11.999998. Rounding to two decimals in a 24-unit icon changes nothing visible.
  • Relative and absolute mixed freely. Optimizers pick whichever form is shorter for each command.

None of this changes what is drawn. To read a path, add spaces between commands; the browser accepts both forms. The guides on optimizing SVG files and editing an SVG by hand cover which of these changes are safe to make yourself.

More in SVG

All guides