SVG path explained: the d attribute and its commands
An SVG path draws any shape from a list of commands in its d attribute: M, L, C, Q, A and Z. What each one means, with examples for lines, curves and arcs.
Published
An SVG <path> draws a shape by following a list of pen commands held in its d attribute: move here, draw a line to there, curve to there, close the shape. Each command is one letter followed by numbers. With ten letters a path can draw anything, which is why most shapes in an exported SVG file are paths.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M 10 10 L 90 10 L 90 90 L 10 90 Z" fill="none" stroke="black" stroke-width="2"/>
</svg>
That reads: move to 10,10. Line to 90,10. Line to 90,90. Line to 10,90. Close. The result is a square. Coordinates are x then y, with x running right and y running down from the top-left corner.
The commands
| Letter | Name | Numbers that follow | What it does |
|---|---|---|---|
M | Move to | x y | Lifts the pen and puts it down at a new point |
L | Line to | x y | Straight line to the point |
H | Horizontal line | x | Straight line across to x |
V | Vertical line | y | Straight line up or down to y |
C | Cubic curve | x1 y1 x2 y2 x y | Curve to x,y shaped by two control points |
S | Smooth cubic | x2 y2 x y | A cubic curve that carries on smoothly from the last one |
Q | Quadratic curve | x1 y1 x y | Curve to x,y shaped by one control point |
T | Smooth quadratic | x y | A quadratic curve that carries on smoothly |
A | Arc | rx ry rotation large-arc sweep x y | Part of a circle or ellipse, ending at x,y |
Z | Close path | none | Straight line back to the start of the shape |
Capital and small letters
A capital letter takes absolute coordinates, measured from the origin. A small letter takes relative coordinates, measured from wherever the pen is now. These three paths draw the same square:
<path d="M 10 10 L 90 10 L 90 90 L 10 90 Z"/>
<path d="M10 10H90V90H10Z"/>
<path d="m10 10h80v80h-80z"/>
Relative commands make a shape easy to move: only the first M changes.
Curves
Curves in a path are Bézier curves. The curve starts at the current point and ends at the last pair of numbers. The control points pull it into shape without lying on it.
<path d="M 10 80 C 30 10, 70 10, 90 80" fill="none" stroke="black"/>
This cubic curve starts at 10,80 and ends at 90,80. It leaves the start heading towards the first control point, 30,10, and arrives at the end coming from the second, 70,10, which gives an arch.
Q works the same way with a single control point: M 10 80 Q 50 10 90 80 is a similar but lower arch.
S and T are shorthand for chains of curves. They leave out the first control point and use the mirror image of the previous curve’s last control point, so the join has no corner:
<path d="M 10 50 C 20 20, 40 20, 50 50 S 80 80, 90 50" fill="none" stroke="black"/>
That is one smooth wave, up and then down.
Arcs
The arc command is the one that needs explaining. It draws part of an ellipse from the current point to a new point:
A rx ry rotation large-arc sweep x y
rx ry: the two radii of the ellipse. Equal values make it a circle.rotation: turns the ellipse, in degrees. It makes no difference to a circle, so it is usually 0.large-arc: 0 or 1.sweep: 0 or 1.x y: where the arc ends.
Two flags are needed because, for a given pair of points and radii, there are four possible arcs. Two ellipses of that size pass through both points, and each one offers a short way round and a long way round. large-arc set to 1 chooses an arc of more than 180 degrees, and 0 chooses the shorter one. sweep set to 1 draws clockwise as seen on screen, and 0 draws anticlockwise.
<path d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="black"/>
This goes from 10,50 to 90,50 on a circle of radius 40, clockwise, so it draws the top half of the circle. Change the sweep flag to 0 and it draws the bottom half.
A quarter-circle pie slice, from the centre out, round and back:
<path d="M 50 50 L 50 10 A 40 40 0 0 1 90 50 Z"/>
An arc whose end is the same as its start draws nothing, so a full circle needs two arcs: M 10 50 A 40 40 0 1 1 90 50 A 40 40 0 1 1 10 50 Z. And if the radii are too small to reach from one point to the other, they are scaled up until the arc just fits.
Several shapes in one path, and holes
Every M starts a new piece, called a subpath, so one <path> can hold many separate outlines. This is how a letter O or a ring is made: an outer outline and an inner one in the same path.
Whether the inner outline becomes a hole depends on the fill-rule. With fill-rule="evenodd" an outline inside another is always a hole. With the default, nonzero, it is a hole only if it is drawn in the opposite direction to the outer one. If a hole comes out filled, set fill-rule="evenodd" on the path.
Why real paths look unreadable
The syntax allows a great deal to be left out, and programs that save SVG use every saving:
- Spaces and commas are interchangeable, and not needed where a letter or a minus sign already separates two numbers:
M10-20meansM 10 -20. - A number may begin with its decimal point, and
.5.5is read as0.5 0.5. - A repeated command letter can be dropped:
L 10 10 20 20 30 10is three lines. - Extra pairs after
Mare treated asL.
So M10 10 90 10 90 90 10 90z is the square again. To read a dense path, paste the whole file, <svg> wrapper included, into the SVG viewer and change one number at a time.
Paths for cutting and plotting
For a cutting machine, laser or pen plotter, the path is the route the tool takes. Each subpath is one continuous cut or one stroke of the pen, and Z matters: a closed path is a piece that can be lifted out, and an open path is only a slit or a drawn line. Fill colour and stroke width do not move the tool. The free SVG library has files prepared for cutting.
Common problems
| What you see | Cause | Fix |
|---|---|---|
| A line drawing shows as a black blob | Paths are filled black by default | Add fill="none" and a stroke |
| Nothing is drawn | No stroke on an unfilled path, or coordinates outside the viewBox | Add a stroke; check the viewBox |
| The arc bulges the wrong way | Sweep flag | Swap it between 0 and 1 |
| The arc takes the long way round | Large-arc flag | Swap it between 0 and 1 |
| The path stops part way | A mistake in d: the path is drawn only up to the error | Look for a missing number or a stray letter after the last good segment |
| The corner where the shape closes looks notched | The last point repeats the first, with no Z | End the shape with Z |
| A hole is filled in | Fill rule | fill-rule="evenodd" |
Questions
Is a path better than <rect> or <circle>? For a plain rectangle or circle the basic shapes are shorter and clearer. A path is needed for everything else, and editors often convert all shapes to paths on export.
Can a path be moved or rotated without rewriting it? Yes, with a transform.
How are the line’s colour and thickness set? With fill and stroke.