SVG Vector Lab logo SVG Vector Lab

Paint and outlines

SVG strokes: width, linecaps, joins, and dash patterns

A stroke follows the centerline of a path. Its width, caps, joins, and dashes can change the visible bounds and personality of an icon even when the underlying geometry stays the same.

Start with stroke and fill

The stroke property paints an outline and stroke-width sets its thickness in the current coordinate system. A path also has a fill by default, so line artwork usually needs fill="none".

<path d="M 20 80 C 60 20 120 20 160 80"
      fill="none" stroke="#276ef1" stroke-width="8" />

A width of 8 extends roughly 4 units to each side of the path centerline. Include that extra area when tightening a viewBox. If the path is clipped at an edge, adding padding is usually better than shrinking the stroke.

Linecap controls open endpoints

stroke-linecap applies to the ends of open subpaths and each visible dash. butt ends exactly at the endpoint. round adds a semicircle. square adds a half-width rectangular extension.

Rounded caps make short icon strokes feel softer and can turn a zero-length subpath into a dot. Square caps make a line visibly longer than its coordinate distance. When matching a design to a pixel grid, account for that extension before moving the endpoints.

Linejoin controls corners

stroke-linejoin applies where segments meet. round creates a rounded outside corner. bevel cuts the corner flat. miter extends the outer edges until they intersect, which preserves a sharp point but can create a very long spike at acute angles.

stroke-miterlimit limits that spike. It compares miter length with stroke width. When the ratio exceeds the limit, the renderer falls back to a bevel-like join. If a corner changes shape after a small geometry edit, inspect both the angle and the miter limit before blaming the path data.

Stroke presentation attributes also have CSS property counterparts. If both are present, CSS wins in the cascade, so check computed styles when changing the attribute appears to do nothing. The MDN stroke-linejoin reference documents the standard values and flags newer values whose browser support still varies.

Build predictable dash patterns

stroke-dasharray alternates painted and empty lengths. An odd-length list is repeated to create an even cycle. stroke-dashoffset shifts where the cycle begins.

<path d="M 20 60 H 180"
      fill="none" stroke="#0a8f8b" stroke-width="6"
      stroke-linecap="round"
      stroke-dasharray="18 10" stroke-dashoffset="4" />

Dash values use the current coordinate system, so a later transform can scale them. To align dashes around a closed outline, measure the path length, choose a cycle that divides it acceptably, and adjust the offset so corners do not receive awkward partial dashes.

Opacity and paint order

stroke-opacity changes only the stroke. The general opacity property composites the entire element, including overlapping fill and stroke, as one group. These can produce different results on translucent artwork.

By default, fill is painted before stroke. The paint-order property can place the stroke behind the fill, which is useful for outlined lettering or icons where half of a thick centered stroke would otherwise cover the interior. Test browser support for the exact rendering targets you need.

Keep a stroke constant while scaling

Add vector-effect="non-scaling-stroke" when transformed geometry should keep a consistent displayed stroke width. This is useful for maps, diagrams, and zoomable interfaces. It can be surprising in exported artwork because the outline no longer scales with the object, so use it intentionally.

  1. Set fill="none" for line-only art.
  2. Reserve at least half the stroke width around bounds.
  3. Choose linecaps based on endpoint length and style.
  4. Check acute joins at the final stroke width.
  5. Test dash alignment on closed paths.
  6. Verify behavior after transforms and at small rendered sizes.

Use the SVG editor's fill and stroke controls to compare these choices live. If the visible outline is correct but the canvas still clips it, adjust the framing with the SVG viewBox guide.