SVG Marker

Learn how the <marker> element defines a reusable symbol -- typically an arrowhead or dot -- that attaches to the start, end, or every vertex of a line or path.

Defining a Marker

A <marker> lives inside <defs> and is never drawn on its own; it's a template, referenced later by url(#id). Its markerWidth and markerHeight set the size of the marker's own viewport, and refX/refY pick which point inside that viewport lines up with the vertex it's attached to -- for an arrowhead, that's usually the tip.

A Basic Arrowhead Marker

<!DOCTYPE html>
<html>
<body>

<svg viewBox='0 0 220 80'>
  <defs>
    <marker id='arrow' markerWidth='10' markerHeight='10' refX='8' refY='5' orient='auto'>
      <path d='M0,0 L10,5 L0,10 Z' fill='#dc2626'/>
    </marker>
  </defs>
  <line x1='20' y1='40' x2='190' y2='40' stroke='#dc2626' stroke-width='3' marker-end='url(#arrow)'/>
</svg>

</body>
</html>

Three properties place markers along a shape: marker-start puts one at the first vertex, marker-end at the last, and marker-mid at every vertex in between (so on a straight line, marker-mid never fires, but on a multi-point polyline or path it appears at each interior point). All three accept the same url(#id) reference, so a single marker definition can be reused everywhere.

Start, Mid, and End Markers on a Polyline

<!DOCTYPE html>
<html>
<body>

<svg viewBox='0 0 240 100'>
  <defs>
    <marker id='dot' markerWidth='8' markerHeight='8' refX='4' refY='4'>
      <circle cx='4' cy='4' r='4' fill='#0f766e'/>
    </marker>
  </defs>
  <polyline points='20,80 80,20 140,80 200,20' fill='none' stroke='#0f766e' stroke-width='2' marker-start='url(#dot)' marker-mid='url(#dot)' marker-end='url(#dot)'/>
</svg>

</body>
</html>
Note: orient='auto' rotates the marker to match the direction of the path at each point -- essential for arrowheads, which look wrong pointing sideways on a diagonal line. Use 'auto-start-reverse' on a marker-start arrow so it points outward instead of back along the same direction as the end arrow.

Sizing and Scaling Markers

By default a marker's coordinate system scales with the stroke width of the line it's attached to (markerUnits='strokeWidth'), so a thicker line automatically gets a proportionally bigger arrowhead. Setting markerUnits='userSpaceOnUse' instead makes the marker's size independent of stroke width, using the same coordinate units as the rest of the SVG.

  • markerWidth / markerHeight set the size of the marker's own viewport
  • refX / refY set the point inside that viewport aligned to the vertex
  • orient is 'auto', 'auto-start-reverse', or a fixed angle in degrees
  • markerUnits is 'strokeWidth' (default, scales with stroke) or 'userSpaceOnUse'
  • marker-start / marker-mid / marker-end choose where along the shape it appears

Arrowhead That Scales with Stroke Width

<!DOCTYPE html>
<html>
<body>

<svg viewBox='0 0 220 100'>
  <defs>
    <marker id='scaleArrow' markerWidth='6' markerHeight='6' refX='5' refY='3' orient='auto' markerUnits='strokeWidth'>
      <path d='M0,0 L6,3 L0,6 Z' fill='#7c3aed'/>
    </marker>
  </defs>
  <line x1='20' y1='30' x2='200' y2='30' stroke='#7c3aed' stroke-width='2' marker-end='url(#scaleArrow)'/>
  <line x1='20' y1='70' x2='200' y2='70' stroke='#7c3aed' stroke-width='8' marker-end='url(#scaleArrow)'/>
</svg>

</body>
</html>
Note: Markers clip their contents to their own viewport by default -- if a custom marker shape looks cut off, either enlarge markerWidth/markerHeight or set overflow: visible on the marker itself.
AttributePurpose
markerWidth / markerHeightDimensions of the marker's own coordinate viewport
refX / refYAnchor point inside the marker aligned to the vertex
orient'auto' rotation to match path direction, or a fixed angle
markerUnitsWhether marker size scales with stroke-width or uses fixed user units
marker-start / -mid / -endWhich vertices of the referencing line or path get the marker

Exercise: SVG Marker

On a multi-segment <polyline>, which marker property draws a marker on every vertex except the first and last?