How SVG Non-Scaling-Stroke Maintains Line Width
This article explains how the
vector-effect="non-scaling-stroke" property functions in
Scalable Vector Graphics (SVG) to maintain consistent line thicknesses.
By default, geometric transformations that scale an SVG element will
also scale its stroke width proportionally. Applying
non-scaling-stroke overrides this behavior, ensuring that
lines retain their exact defined pixel or unit width regardless of
element scaling, coordinate transformations, or user zoom
interactions.
The Default Scaling Problem in SVG
In standard SVG rendering, elements exist within a user coordinate
system. When a transformation—such as a
transform="scale(...)", a changing viewBox, or
a responsive container resize—is applied to an SVG shape, the coordinate
space itself expands or contracts.
Because stroke thickness is defined within this local coordinate
system, it scales directly with the geometry. For example, a path with
stroke-width="2" inside an SVG that is scaled up by a
factor of 4 will visually render with an effective stroke width of 8
pixels. While this is mathematically correct for proportional vector
scaling, it is often undesirable for user interface icons, responsive
borders, and interactive mapping systems.
How non-scaling-stroke Works Internally
The vector-effect attribute modifies how the SVG
rendering engine calculates stroke geometry relative to the Current
Transformation Matrix (CTM).
When vector-effect="non-scaling-stroke" is declared on
an SVG element:
- Geometry Transformation: The shape’s underlying path, vertices, and fill boundaries are transformed according to the local matrix and parent transformations as usual.
- Stroke Decoupling: Before rasterizing the outline, the rendering engine decouples the stroke width from the local coordinate space. It references the host viewport coordinate system (device space) rather than the local user space.
- Inverse Transformation: Mathematically, the renderer calculates the scale component of the combined transformation matrix and applies its inverse to the stroke width. If the shape is scaled by \(S_x\) and \(S_y\), the stroke width is adjusted by \(1 / S\) before rendering.
- Final Rasterization: The stroke is drawn along the
transformed path using the original, unscaled measurement defined in the
stroke-widthattribute.
As a result, zooming into the graphic makes the shapes larger, but the borders and paths remain sharp, crisp, and visually identical in thickness.
Implementation Methods
The non-scaling behavior can be applied directly within the SVG markup or through CSS.
SVG Attribute
<svg viewBox="0 0 100 100" width="400" height="400">
<circle cx="50" cy="50" r="40"
stroke="black"
stroke-width="2"
fill="none"
vector-effect="non-scaling-stroke" />
</svg>CSS Property
.uniform-stroke {
vector-effect: non-scaling-stroke;
}<path class="uniform-stroke" d="M10 10 H 90 V 90 H 10 Z" stroke="blue" stroke-width="1.5" />Primary Use Cases
- Interactive Maps: Geographic paths, borders, and roads maintain a readable line weight when users zoom in and out of the map canvas.
- Responsive UI Icons: A single set of SVG icons can scale across multiple screen resolutions while maintaining the exact line weight defined by the design system.
- CAD and Architectural Diagrams: Dimension lines, technical schematics, and blueprint annotations remain legible at any magnification level.