How To Create Patterns in SVG

You can create patterns in SVG to fill or stroke an object using a predefined graphic object which can be replicated horizontally and vertically to fill another object or stroke. It can be defined using a pattern element and then referenced by properties fill and stroke on a given graphics element to indicate that the given element shall be filled or stroked with the referenced pattern. While creating patterns in SVG, attributes x, y, width, height and patternUnits define a reference rectangle.


Creating a Simple Pattern


Here is an example to create a simple pattern, which encloses the <path> elements that describes tile that can be used in a <pattern> element.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 Q 35 130 65 65 T 130 130"
style="stroke: red; fill: red;"/>
<path d="M 10 10 h120 v120 h-120 z"
style="stroke: blue; fill: none;"/>
</svg>
In the example given below, the shape created with <path> element in the example given above is now used in <pattern> element.
<svg width="150" height="150"
xmlns="http://www.w3.org/2000/svg">
<pattern id="simple" patternUnits="userSpaceOnUse"
x="0" y="0" width="20" height="20"viewBox="0 0 20 20" >
<path d="M 2 2 Q 7 20 10 10 T 20 20"
style="stroke: red; fill: red;"></path>
</pattern>
<path d="M 10 10 h120 v120 h-120 z"
fill="url(#simple)" stroke="blue"></path>
</svg>
Here a preview of the examples given above.

Using patternUnits Attribute


The attribute 'patternUnits' defines the coordinate system for attributes x, y, width and height. x, y, width and height indicate how the pattern tiles are placed and spaced. If the attribute is not specified, the effect is as if a value of zero were specified.

There may be two values for patternUnits attribute which are userSpaceOnUse and objectBoundingBox. An object's bounding box is the smallest rectangle that completely encloses a particular graphic object. If "userSpaceOnUse" is used, the user coordinate system for attributes x, y, width and height is established with taking the current user coordinate system. If "objectBoundingBox" is used, the user coordinate system for attributes x, y, width and height is established using the bounding box of the element to which the pattern is applied. If attribute patternUnits is not specified, then the effect is as if a value of objectBoundingBox were specified.

In the example given below, small rectangles are tiled within a large rectangle using patternUnits attribute in SVG with defining x, y, width and height of the rectangle.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="Pattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" >
<path d="M 0 0 h5 v5 h-5 z"
style="stroke: brown; fill: none;"/>
</pattern>
</defs>
<rect fill="url(#Pattern)" stroke="gray" stroke-width="3"
x="10" y="10" width="150" height="150" />
</svg>

Using patternContentUnits Attribute


PatternContentUnits attribute defines the coordinate system for the contents of the 'pattern', which has no effect if attribute view Box is specified. This attribute also uses same values as patternUnits attribute.

Similar to the patternUnits attribute, PatternContentUnits attribute has also two values userSpaceOnUse and objectBoundingBox. You should decide what units are to be used to express the pattern data itself. By default, the patternContentUnits attribute is set to userSpaceOnUse. If you set the attributes to objectBoundingBox, the path data points are expressed in terms of patternContentUnits set to objectBoundingBox.

In the following example, patternContentUnits attribute is used to define the coordinate system for the contents of the 'pattern', where the rectangle is filled with circles to create a pattern.  
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="circle"
patternUnits="userSpaceOnUse"
patternContentUnits="userSpaceOnUse"
x="0" y="0" width="36" height="36">
<circle cx="12" cy="12" r="12"
style="fill: red; stroke: blue;"/>
</pattern>
</defs>
<rect x="10" y="10" width="150" height="150"
style="fill: url(#circle); stroke: black;"/>
</svg>

Using patternTransform Attribute


PatternTransform attribute contains the definition of an optional additional transformation from the pattern coordinate system onto the target coordinate system. This allows for things such as skewing the pattern tiles. This additional transformation matrix is post-multiplied to any previously defined transformations, including the implicit transformation necessary to convert from object bounding box units to user space. If attribute patternTransform is not specified, then the effect is as if an identity transform were specified.

The following example creates a rectangle filled with small rectangles patterns, which are rotated with 45 degrees using patternTransform attribute in SVG. 
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="rectangle"
patternUnits="userSpaceOnUse"
patternTransform = "rotate(45)"
x="0" y="0" width="36" height="36">
<path d="M 2 2 h20 v20 h-20 z"
style="stroke: blue; fill: pink;"/>
</pattern>
</defs>
<rect x="10" y="10" width="150" height="150"
style="fill: url(#rectangle); stroke: gray;" stroke-width="2"/>
</g>
</svg>

Creating Nested Patterns


Pattern  can also be filled with another pattern, they are called nested patterns. Since nested patterns are rarely necessary, but there are some effects you can't easily achieve without nested patterns.

The following example creates a rectangle filled with circles, all of the circles are also filled with another types of patterns.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="tile"
patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10">
<path d="M 0 0 Q 3 10 5 5 T 10 10"
style="stroke: red; fill: lime;"/>>
</pattern>
<pattern id="nested"
patternUnits="userSpaceOnUse"
x="5" y="5" width="36" height="36">
<circle cx="12" cy="12" r="12"
style="fill: url(#tile); stroke: black;"/>
</pattern>
</defs>
<rect x="10" y="10" width="150" height="150"
style="fill: url(#nested); stroke: blue;"/>
</svg>

Read Next: How To Work With Text in SVG