How to Use SVG Patterns
SVG patterns are one of several paint options that we have for coloring the fills and strokes of shapes and text. While generally regarded as one of the more complex options, establishing a foundation and understanding the basic syntax can make more seemingly complex patterns much more obtainable.
SVG patterns provide for very unique design opportunities. We are essentially defining a canvas within a target shape or text, which is then repeated (or tiled) throughout, enabling more detailed design outside of solid color fills and strokes.
In this article we will discuss the basic syntax and attribute options for SVG patterns and then review some examples for further understanding.
Background Knowledge
Before we get started it’s important to note that this article assumes a basic knowledge of how inline SVG works. There are a lot of great resources out there on getting started with inline SVG in general, like this one at CSS Tricks, and this one on SitePoint.
Concerning the use of SVG shapes the W3C has a great guide to get you started.
Fill Patterns
Let’s take a look at the syntax of a basic SVG pattern and then walk through the specific attribute options.
With Postcards Email Builder you can create and edit email templates online without any coding skills! Includes more than 100 components to help you create custom emails templates faster than ever before.
Free Email BuilderFree Email Templates<svg> <defs> <pattern id="basicPattern" x="10" y="10" width="40" height="40" patternUnits="userSpaceOnUse"> <circle cx="20" cy="20" r="20” fill= "#64bee3" /> </pattern> </defs> <rect x="10" y="10" width="200" height="200" stroke= "#333333" stroke-width="2" fill="url(#basicPattern)" /> </svg>
This code will render the following pattern within a rectangle:
The <svg>
contains a <defs>
element which allows us to create reusable definitions to be called on later. These definitions have no visual output until they are referenced using their unique ID within the stroke
and/or fill
attributes.
The rectangle is located within the <svg>
, but outside of the <defs>
element where we have defined our pattern. The pattern is then applied to the rectangle through the “fill” attribute: `fill="url(#basicPattern)”`
.
Attributes
While there are a great number of SVG specific attributes, this article will touch on those essential for generating and manipulating basic SVG patterns.
Perhaps the most significant and more challenging concepts to understand in regards to SVG patterns are the coordinates for which each pattern detail is mapped, so these attributes specifically will be addressed in the following descriptions.
ID
Each pattern requires a unique ID in order to be reference via the stroke
and/or fill
attributes of SVG shapes or text.
x,y, width, height
The x and y attributes within the <pattern>
element define how far into the shape the pattern will start. Width and height used within the <pattern>
element define the actual width and height of the allotted pattern space.
With Startup App and Slides App you can build unlimited websites using the online website editor which includes ready-made designed and coded elements, templates and themes.
Try Startup App Try Slides AppOther ProductsFor example, the <pattern>
element referenced above contains the following values: x="10" y="10" width="40" height="40”
. The pattern will start 10px in from the start of the x axis, 10px in from the start of the y axis, and essentially create a “canvas” that is 40px wide, and 40px high.
Determining within what coordinate system these values are applied is determined by the values within the patternUnits
and patternContentUnits
attributes.
patternUnits
The patternUnits
attribute defines the coordinates for which x, y, width, and height are referenced. The two options here are userSpaceOnUse
and objectBoundingBox
.
Used in the context of patterns, a value of userSpaceOnUse
results in a pattern coordinate system that is determined by the coordinate system for the element referencing the <pattern>
(like the rectangle in the above example) “stroke” and/or “fill”.
A value of objectBoundingBox
establishes the mapping coordinate system of x, y, width, and height as the bounding box of the element to which the pattern is applied (the pattern target).
If left unspecified the default value is objectBoundingBox
.
patternContentUnits
The patternContentUnits
attribute values are the same as the values for patternUnits
, objectBoundingBox
and userSpaceOnUse
, except the coordinate system is now being defined for the contents of the pattern.
Unlike patternUnits
, if this value is left unspecified it defaults to “userSpaceOnUse”. This means that unless one or both of these attributes are specified, the shapes drawn within the <pattern>
are being drawn in a different coordinate system than the <pattern>
element itself is using.
An approach to making this less difficult would be to define patternUnits=”userSpaceOnUse”
within the <pattern>
element. By default patternContentUnits
will be set to userSpaceOnUse
, ensuring that they are both now working within the same coordinate space, which we will discuss further in the next section.
Also worth noting here is that this value will have no effect if you have already specified the viewBox attribute coordinates in the <pattern>
element.
A Closer Look at Pattern Units
Pattern units are both the most significant and most complex aspect of SVG patterns. As mentioned, patternUnits
and patternContentUnits
have different values by default, making it important to set either one of them to coordinate with the other for a consistently positioned pattern area.
Setting patternUnits=”userSpaceOnUse”
will ensure it is working within the same coordinate system as patternContentUnits
and is the much more straightforward option. If we were to resize the target shape/text set within this coordinate system, the pattern will repeat to fill the additional space.
Setting patternContentUnits=”objectBoundingBox”
will also ensure consistent coordinate space. If we were to resize the target shape/text set within this coordinate system, the pattern will scale to fill the additional space without repeating. In order to ensure proper scaling values within this system must be set in percentages or decimal based numbers.
Working within an objectBoundingBox
system, however, can prove difficult. There seems to be a number of bugs when working within this space, and the idea of scaling in general is not really true to the concept of a repeating, tiled pattern.
For reference here is a look at the details for a basic pattern set within the objectBoundingBox
coordinate space:
<svg> <defs> <pattern id="boundingPattern" width=".50" height=".50" patternContentUnits="objectBoundingBox"> <circle cx=".250" cy=".250” r=".1" fill="#ec7677" /> </pattern> </defs> <rect x="2" y="2" width="200" height="200" stroke="#333333" stroke-width="2" fill="url(#boundingPattern)" /> </svg>
If we were to expand the width
and height
of the target shape referencing the pattern, the circles will scale appropriately; there will always be only four circles within the rectangle.
A Note on Sizing
It can seem like there are a lot of width
and height
values being specified within the SVG, the pattern, and the shapes involved in generating SVG patterns which can very quickly become overwhelming.
The width
and height
within the <pattern>
element define how far the pattern should go before it begins repeating itself. These values essentially determine the canvas size of the pattern area.
The width
and height
within the pattern shapes determine their size, but the size cannot exceed the width
and height
set within the <pattern>
element; the excess of any shape set larger than the bounds set by <pattern>
will not render.
Additional Example
Now that we have a stronger understanding of SVG pattern attribute options, let’s take a more in-depth look at another example that further utilizes these values options:
<svg> <defs> <pattern id="secondPattern" x="2" y="2" width="20" height="20" patternUnits="userSpaceOnUse"> <rect x="5" y="5" width="10" height="10" fill= "#876fc1" /> </pattern> </defs> <rect x="2" y="2" width="200" height="200" stroke= "#333333" stroke-width="2" fill="url(#secondPattern)" /> </svg>
The Dimensions
Our SVG shape is 200px by 200px, our pattern “canvas” is 20px by 20px, and the pattern shape itself is 10px by 10px. This allows for 10 pattern units (20px by 20px) to fit across the shape (200px by 200px).
Within each pattern unit there is a rectangle (10px by 10px) with an x and y value of 5px. This means that on the top and left sides of each rectangle there is a 5px padding from the sides of the <pattern>
bounds.
Both the SVG shape itself and the pattern start 2px in from the left and 2px in from the top, to ensure the shape’s border is not hidden out of view.
Altering x and y Values
If we set this pattern rectangle to the same size as the pattern “canvas” (20px by 20px) and set its x and y values to “0” the SVG shape would fill solid purple. Adding x and y values greater than “0” for the shape inside the pattern pushes the shape into the pattern along the appropriate axis, with any overflow simply not being visible.
Depending on the values used throughout, a greater x and y value on the rectangle within the pattern can make the rectangle appear as if it is getting smaller, even though the width
and height
are the same. This is because the shape is moving beyond the bounds set within the <pattern>
element, and if you then expand the width and height within the <pattern>
it will reveal the parts of the shape that had been cut out of view.
The following pattern is identical to that on the rectangle above, except with different x and y values on the purple pattern shape: x="15" y="15”
.
It appears as if the pattern rectangles have gotten smaller, but we have just pushed it further down and over an additional 10px, moving a portion of it off the pattern canvas.
Nested Patterns
It is also possible to fill a pattern with another pattern.
<svg> <defs> <pattern id="yellowPattern" x="5" y="5" width="75" height="75" patternUnits="userSpaceOnUse"> <circle cx="22" cy="22" r="14" stroke="#f19450" stroke-width="2" fill="#f6bf35" /> </pattern> <pattern id="greenPattern" x="10" y="10" width="50" height="50" patternUnits="userSpaceOnUse"> <rect x="2" y="2" width="30" height="30" stroke="#5cbc8f" stroke-width="2" fill="url(#yellowPattern)" /> </pattern> </defs> <rect x="2" y="2" width="200" height="200" stroke="#333333" stroke-width="2" fill="url(#greenPattern)" /> </svg>
Paths as Patterns
Paths can be used within patterns as well.
<svg> <defs> <pattern id="pathPattern" x="4" y="4" width="25" height="25" patternUnits="userSpaceOnUse"> <path d="M 0 0 Q 5 20 10 10 T 20 20" stroke="#f0934e" fill="none" /> </pattern> </defs> <rect x="2" y="2" width="200" height="200" stroke= "#333333" stroke-width="2px" fill="url(#pathPattern)" /> </svg>
Filling Text
Filling <text>
with a pattern is very similar to filling a shape.
<svg width="600" height="400"> <defs> <pattern id="textPattern" x="7" y="7" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"> <rect x="5" y="5" width="5" height="5" fill= "#876fc1" /> </pattern> </defs> <text x="0" y="50%" font-size="200" fill="url(#textPattern)">Text</text> </svg>
Browser Support
Browser support for inline SVG is strong across modern desktop and mobile browsers, though no support present in Opera Mini.
Conclusion
In this article we reviewed the basic syntax for SVG patterns, reviewed the meaning for potential attributes for further customization, and then dove into some examples for further understanding.
Hopefully establishing a basic foundation of how these patterns work inspires you to test the limits of their capabilities with more complex shapes and paths.