The usual approach to making diagonal designs in web page backgrounds is either to use a little trigonometry to create patterns that repeat and tile seamlessly in a square, or to use a repeating CSS linear gradient. Both have their limitations and complications, all of which are neatly addressed by using an SVG pattern instead.
SVG Tiles
An SVG pattern is pretty much what it implies: an area that holds its own drawing information, which is then tiled across a larger space.
In many cases, it’s easier to draw the pattern first, creating the SVG from the “inside out”. The basic template is:
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs>
<pattern id="pinstripe" patternUnits="userSpaceOnUse" width="50" height="50">
<line x1="25" y="0" x2="25" y2="50" stroke="goldenrod" stroke-width="25" />
</pattern>
</defs>
</svg>
There’s several things to note here:
- The SVG doesn’t have a
viewBox
, but uses awidth
andheight
instead, with both attributes set to100%
. - The
<pattern>
has its ownwidth
andheight
.patternUnits="userSpaceOnUse"
means that these limits are used inside the pattern itself: they become the limits of the world the pattern occupies. - The
<pattern>
is defined inside a<defs>
element, and<defs>
will not render until they are referenced. For this reason, you might want to draw your SVG pattern in another document as an ordinary vector, ideally inside aviewBox
of the same dimensions as the pattern (50 × 50, in this case). This allows you to visibly alter the pattern components before placing them inside the context of the<pattern>
itself. - In this case, our pattern consists of a vertical line that, due to its stroke, occupies exactly half of the pattern area.
We’re not quite done yet: to see the result, the pattern must be used to fill an SVG element. A rectangle makes the most sense:
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs>
<pattern id="pinstripe" patternUnits="userSpaceOnUse" width="50" height="50">
<line x1="25" y="0" x2="25" y2="50" stroke="goldenrod" stroke-width="25" />
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#pinstripe)" />
</svg>
The <rect>
occupies the entire space of the SVG. It doesn’t matter if it is declared before or after the <defs>
: the fill
will find the referenced id
of the pattern regardless:
Saved as pinstripe.svg
, the result is applied as a background image to an HTML page, in much the same way as before:
body {
background-color: darkblue;
background-image: url('pinstripe.svg');
}
The result tiles across the page just like before. At this point you might be justified in saying “So what? We did exactly that in the previous example, with less markup.”
Ah, but here’s where it gets neat. Because the <pattern>
is its own little world, we can do anything we want to it and have those changes reflected in the broader context of the page. Back in pinstripes.svg
, alter the opening <pattern>
tag to the following:
<pattern id="pinstripe" patternTransform="rotate(45)"
patternUnits="userSpaceOnUse" width="50" height="50">
Save the file, and refresh the HTML page. You’ll see that the background pattern is now at a 45° angle, with no need for judgement about position or tile size. The rotation can take any value, with the same result:
<pattern id="pinstripe" patternTransform="rotate(33)"
patternUnits="userSpaceOnUse" width="50" height="50">
Again, the result tiles and repeats seamlessly. Want thinner lines? just reduce the stroke-width
on the line
element. Fewer lines on the page? Add a background-size
declaration to the CSS.
Conclusion
Understanding the basics of SVG patterns opens up a world of creative possibilities for web page backgrounds: you can layer multiple patterns, creating complex seamless tiles easily from vector shapes. I’ll demonstrate some of those in the next article.
Credit for making me aware of this technique is entirely due to Amelia Bellamy-Royds, who’s technical SVG books I’ve had the pleasure of reviewing over the past few weeks: it was in her writing that I discovered the inspiration for this article.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/qdGEwE