Understanding the SVG fill-rule Property
The SVG fill-rule property determines whether a specific
point inside a complex, overlapping, or self-intersecting shape is
treated as “inside” (filled with color) or “outside” (left transparent).
It achieves this by using an algorithm called ray casting to evaluate
intersecting path segments. This property accepts two primary
values—nonzero (the default) and evenodd—each
calculating interior regions differently based on path crossings and
winding direction.
The Ray Casting Principle
To decide whether any given point on a canvas should be filled, the
rendering engine casts an imaginary ray from that point in any direction
to infinity. As this ray extends outward, it counts every time it
crosses a path segment. How the engine interprets these crossings
depends entirely on the active fill-rule.
The nonzero Rule
(Default)
The nonzero value determines fill status based on the
total winding number of the path segments the ray crosses. Direction
(winding order) is critical for this rule.
- A counter starts at zero (
0). - An imaginary ray is drawn from the test point to infinity.
- Every time the ray crosses a path drawn from left to
right (or clockwise relative to the point), add
1to the counter. - Every time the ray crosses a path drawn from right to
left (or counter-clockwise relative to the point), subtract
1from the counter. - If the final count is non-zero, the point is inside the shape and gets filled.
- If the final count equals zero, the point is outside the shape and remains unfilled.
Practical Behavior: * Hollow
Shapes: If an inner subpath is drawn in the opposite direction
of the outer subpath (e.g., clockwise outer circle, counter-clockwise
inner circle), the counts cancel out (1 - 1 = 0), creating
a cutout/hole. * Solid Overlaps: If overlapping
subpaths are drawn in the same direction, the sum remains non-zero
(1 + 1 = 2), causing overlapping areas to remain solid.
The evenodd Rule
The evenodd rule determines fill status simply by
counting the total number of path crossings, completely ignoring the
direction in which the paths were drawn.
- A counter starts at zero (
0). - An imaginary ray is drawn from the test point to infinity.
- Every time the ray crosses any path segment, add
1to the counter. - If the total number of crossings is odd, the point is inside and gets filled.
- If the total number of crossings is even, the point is outside and remains unfilled.
Practical Behavior: * Path direction has zero impact on the result. * Alternating overlaps naturally create nested cutouts: the outermost layer is filled (1 crossing), the next inner layer is empty (2 crossings), the next is filled (3 crossings), and so on.
Summary of Differences
| Feature | nonzero (Default) |
evenodd |
|---|---|---|
| Path Direction Matters | Yes (Clockwise vs. Counter-Clockwise) | No |
| Evaluation Method | Net sum of directional crossings | Total count of crossings |
| Filled Condition | Result ≠ 0 |
Result is an odd number |
| Common Use Case | Complex icons with controlled cutouts | Geometric patterns, concentric shapes, CAD/GIS paths |