It is possible to pre-define certain graphical elements, such as shapes or gradients or even text, and use them repeatedly throughout an SVG document.

<defs>

The <defs> element sets out the definition block of an SVG document and appears at the beginning of the file after the <svg>, <title> and <desc> elements. It is a container element only and has no display attributes. The opening tag is <defs> and the closing tag is </defs>. The objects defined in a definition block are not rendered until they are referenced by another element or attribute.

<marker>

Markers can be used to annotate the starting point, the vertices, or ending point of a <line>, <polyline>, <polygon> or <path>. (A line has no vertices, only starting and ending points.) Markers are defined in the definitions block using the <marker> tag and have the following attributes:

AttributePurposeValueDefault
idUnique identifier.name
markerHeightControl the height of the marker viewport.number or number plus unit of measurement3
markerUnitsDefine the coordinate system for markerHeight, markerWidth and the contents of the <marker>.strokeWidth | userSpaceOnUsestrokeWidth
markerWidthControl the width of the marker viewport.number or number plus unit of measurement3
orientControl the orientation of the marker relative to the shape to which its attached.auto | auto-start-reverse | angle in degreesauto
preserveAspectRatioControl how the marker may be deformed to fit into the SVG document.none | xMinYMin | xMinYMid | xMinYMax | xMidYMin | xMidYMid | xMidYMax | xMaxYMin | xMaxYMax | xMaxYMax optionally followed by meet | slicexMidYMid meet
refXThe x-coordinate of the reference point of the marker.number | left | centre | right0
refYThe y-coordinate of the reference point of the marker.number | top | centre | bottom0
viewBoxThe bounds of the marker viewBox.x-coordinate y-coordinate width height

I confess that I have not used markers before but they look like a useful tool so I have included them on this page.

Examples

Here we define three markers called arrow, dot and square in the <defs> section of the document. We have made them partially transparent so that we can see how they sit on the path. The red dot is at the start of the black path, the green squares (which are rotated through 45°) appear at the vertices (the joins between two path elements), and the blue arrow is at the end, pointing in the direction of the path. Some browsers may also render a green square at the midpoint of the arc which is not a vertex.

<defs>   <marker id=”arrow” viewBox=”0 0 10 8″ markerHeight=”8″ markerWidth=”10″ markerUnits=”strokeWidth” orient=”auto” refX=”4″ refY=”4″>     <path d=”M 0,0 L 10,4 L 0,8 L2,4 Z” fill=”#0000ff” fill-opacity=”0.5″/>   </marker>   <marker id=”dot” viewBox=”-5 -5 10 10″ markerHeight=”10″ markerWidth=”10″ markerUnits=”strokeWidth” orient=”auto” refX=”0″ refY=”0″>     <circle cx=”0″ cy=”0″ r=”5″ fill=”#ff0000″ fill-opacity=”0.5″/>   </marker>   <marker id=”square” viewBox=”-5 -5 10 10″ markerHeight=”10″ markerWidth=”10″ markerUnits=”strokeWidth” orient=”45″ refX=”0″ refY=”0″>     <polygon points=”-5,-5 5,-5 5,5 -5,5″ fill=”#00ff00″ fill-opacity=”0.5″/>   </marker> </defs> <path d=”M 30,100 L 150,50 A 10,20 -45 0,0 300,30 L 470,200″ fill=”none stroke=”#000000″ stroke-linecap=”round” stroke-width=”3″ marker-start=”url(#dot)” marker-mid=”url(#square)” marker-end=”url(#arrow)”/>

Now consider how the markerUnits attribute affects the size of the marker. The size of the marker scales with the stroke-width of the line if the markerUnits is set to strokeWidth. Otherwise, the size of the marker remains static.

marker markerUnits: strokeWidth / line stroke-width: 2 marker markerUnits: strokeWidth / line stroke-width: 4 marker markerUnits: strokeWidth / line stroke-width: 8 marker markerUnits: userSpaceOnUse / line stroke-width: 2 marker markerUnits: userSpaceOnUse / line stroke-width: 4 marker markerUnits: userSpaceOnUse / line stroke-width: 8

<symbol>

This is another element that I have never used before. If and when I ever figure it out, I will add content here.

<use>

The <use> element references another element in the SVG document. A copy of this other element is rendered in place of the <use> element. <use> takes a small number of attributes:

AttributePurposeValueDefault
heightControl the height of the element if the element has a viewBox.number0
hrefThe URL of the element which needs to be duplicated.name
widthControl the width of the element if the element has a viewBox.number0
x,yx- and y-coordinates of the element.number0
xlink:hrefDeprecated. Do not use!

It also takes styling attributes but it cannot override any styling attributes already set in the element.

Examples

In each case, the black dot shows the (x,y) coordinates of the relevant <use> element.

#rhombus as styled by <use> #styledRhombus as defined #styledRhombus as restyled by <use> #blueCircle as defined #purpleCircle as defined <defs>   <polygon id=”rhombus” points=”-40,-25 60,-25 40,25 -60,25″/>   <polygon id=”styledRhombus” points=”-40,-25 60,-25 40,25 -60,25″ fill=”#ff0000″ fill-opacity=”0.3″ stroke=”#800000″ stroke-width=”3″/>   <circle id=”blueCircle” cx=”0″ cy=”0″ r=”50″ fill=”#00ffff” stroke=”#0000ff” stroke-width=”3″/>   <circle id=”purpleCircle” cx=”50″ cy=”50″ r=”50″ fill=”#ff00ff” stroke=”none”/> </defs> <use href=”#rhombus” x=”100″ y=”50″ fill=”none” stroke=”#ff0000″ stroke-width=”3″/> <use href=”#styledRhombus” x=”100″ y=”150″/> <use href=”#styledRhombus” x=”100″ y=”250″ fill=”none” stroke=”#0000ff/”> <use href=”#blueCircle” x=”100″ y=”375″/> <use href=”#purpleCircle” x=”100″ y=”475″/>
  • #rhombus: It is defined without any styling so the styling in the <use> element (no fill, red stroke of width 3) is used. Since the shape is defined with a centre point of (0,0), the (x,y) coordinates of the <use> command put the figure right where we think it should go.
  • #styledRhombus: It is defined with styling (transparent red fill, dark red stroke of width 3). The <use> element consists simply of the href, x and y attributes.
  • #styledRhombus: The <use> element attempts to restyle the shape with no fill and a blue stroke. However, styling attributes in the <use> element cannot override styling attributes in the definition.
  • #blueCircle: It is defined with styling (cyan fill, blue stroke of width 3). The <use> element consists simply of the href, x and y attributes. Since the circle is defined with a centre point of (0,0), the (x,y) coordinates of the <use> command put the figure right where we think it should go.
  • #purpleCircle: It is defined with styling (magenta fill, no stroke). The <use> element consists simply of the href, x and y attributes. However, this circle is defined with its centre at (50,50). The (x,y) coordinates of the <use> command place the circle 50 units farther right and down than expected.

If possible, define your shapes centred on (0,0) to avoid unexpected placement.

It is also possible to use the various transforms in place of the (x,y) point to place the defined object.