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.

      <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:

SVG Patterns

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.

For 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>

Bounding pattern

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>

Second pattern

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”.

Different xy

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>

Nested pattern

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>

Path pattern

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>

Text pattern

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.

Joni Trythall

Joni Trythall learns web design by day, and forgets it all by night. She is constantly trying to combine her love of learning code with her long time obsession of coloring mostly in the lines. Joni lives in always sunny Seattle, WA. You can find her code ramblings at jonibologna.com, Google+ or @jonitrythall.

Newsletter

1 Comment
  1. ruggero Jul 8, 3:38 pm

    Good article, I really think SVG is going to be a little revolution in the markup workflow.
    I would point out the PatternBolt project on GitHub: http://buseca.github.io/patternbolt/ it’s a SVG pattern library: we often use common pattern like stripes, dots or crosses, this library make it easy to insert it in the website, just adding CSS classes.

    Reply
    +3

Leave a Reply

*
* Minimum length: 20 characters