Blog · Path geometry
SVG path data is a small drawing language with state.
Understand the current point, subpaths, curve controls, arc flags, closure, fill rules, and precision before changing path numbers.
Every command reads and updates the current point.
Path data is processed from left to right. M starts a subpath, L draws a line, H and V constrain a line to one axis, C and Q draw cubic and quadratic Bézier curves, A draws an elliptical arc, and Z closes the current subpath. Lowercase commands use coordinates relative to the current point; uppercase commands use the current user coordinate system.
A command letter can often be followed by multiple coordinate sets. The extra sets repeat the same operation, except that coordinate pairs after the first moveto are treated as line commands. Compact syntax is useful for delivery, but explicit commands are easier to inspect while diagnosing malformed geometry.
- Absolute commands describe positions in user space
- Relative commands describe offsets from the current point
- Omitted command letters repeat the preceding operation when its grammar allows
A path can contain several independent subpaths.
Each moveto begins a new subpath without creating a new path element. This is how one path can represent separate islands, holes, or disconnected strokes while sharing paint and transformation. The current point jumps to the new start, but earlier subpaths remain part of the same fill and stroke calculation.
Closepath is not always equivalent to drawing a final line back to the start. Closing creates an explicit join between the final and initial segments; an unclosed line ending at the same coordinate still has two caps. That difference is visible with thick strokes, non-round joins, markers, and dash patterns.
Bézier control points guide tangents, not checkpoints.
A quadratic Bézier segment has one control point and a cubic segment has two. The curve normally does not pass through these controls. The line from the start to the first control determines the starting tangent; the line from the final control to the endpoint determines the ending tangent. Control distance influences how strongly the curve is pulled in that direction.
The smooth S and T commands infer a control by reflecting the relevant control point from the preceding compatible curve around the current point. If the preceding segment is not compatible, the inferred control equals the current point. Smooth commands reduce data, but an editor must expand their context correctly before moving a node independently.
- Q uses one control point; C uses two
- S continues a cubic tangent when the previous command permits it
- T continues a quadratic tangent when the previous command permits it
The arc command selects one of several possible ellipses.
An A command provides x-radius, y-radius, x-axis rotation, a large-arc flag, a sweep flag, and the endpoint. The start point comes from the current path state. Those values do not specify a centre directly: the renderer derives an ellipse and chooses one of the possible connecting arcs.
The large-arc flag chooses between an arc no greater than 180 degrees and the complementary arc; the sweep flag chooses its direction in the current coordinate system. If the supplied radii are too small to connect the endpoints, the SVG algorithm scales them up. A zero radius makes the segment render as a line, which is useful to remember when an expected curve disappears.
Fill rules determine which enclosed regions are inside.
Stroke follows every subpath, but fill must classify regions. The nonzero rule counts signed crossings and is affected by subpath direction. It works naturally for consistently wound outer contours and oppositely wound holes. The evenodd rule counts crossings without direction and alternates between outside and inside.
Two shapes can therefore use identical visible outlines yet fill differently because their subpath order or direction changed. Boolean operations, reversing paths, and combining shapes should preserve or deliberately normalize winding together with the chosen fill rule.
- nonzero uses signed winding
- evenodd uses crossing parity
- Open subpaths are implicitly closed for filling but remain open for stroking
Reduce path data only after defining an error budget.
Rounding every number to the same decimal count is simple but not always safe. The visible error depends on document scale, later transforms, stroke width, animation, clipping, and how closely adjacent segments must meet. Small coordinate changes can open seams, alter tangents, or move an arc to a noticeably different solution.
Optimization should compare rendered and geometric results at the sizes that matter. Remove redundant commands and precision gradually, retain enough digits for shared boundaries, and test fills, strokes, markers, and clipping separately. A shorter path that changes topology is not an optimization.
- Inspect the current point where a path first diverges
- Expand shorthand commands while debugging
- Check closure, winding, and arc flags before adjusting control points
- Measure visual error after transforms, not only in source coordinates