Chapter 24: SVG Patterns
What is an SVG Pattern really?
A pattern is a small piece of SVG artwork (a “tile”) that gets repeated infinitely in both directions (like tiles on a bathroom floor) to fill a shape.
- You define the tile once inside <defs>
- You give the pattern an id
- Then any shape can use it with fill=”url(#myPattern)”
- The browser automatically repeats the tile to cover the entire area of the shape
This is vector-based repeating fill — perfect when you want something more interesting than solid color or gradient.
Basic structure – The <pattern> element
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<svg width="500" height="400"> <defs> <pattern id="myPattern" ...attributes...> <!-- Your repeating artwork goes here: rect, circle, path, text, image, etc. --> </pattern> </defs> <!-- Use it --> <rect x="40" y="40" width="420" height="320" fill="url(#myPattern)" /> </svg> |
Most important attributes on <pattern>
| Attribute | Meaning / Purpose | Common values | Default | Very important? |
|---|---|---|---|---|
| id | Name to reference it | “dots”, “stripes”, “hearts” | — | ★★★★★ |
| width / height | Size of one tile (the repeating unit) | 20, 40, “10%”, 50 | 0 (invisible!) | ★★★★★ |
| patternUnits | Units for width/height/x/y | “objectBoundingBox” or “userSpaceOnUse” | userSpaceOnUse | ★★★★☆ |
| patternContentUnits | Units for the content inside the pattern | “objectBoundingBox” or “userSpaceOnUse” | userSpaceOnUse | ★★★☆☆ |
| x / y | Offset of the first tile (rarely needed) | 0, 5, “10%” | 0 | ★★☆☆☆ |
| patternTransform | Rotate/scale/skew the entire pattern | “rotate(45)” | none | ★★☆☆☆ |
Golden rule for beginners (use this 90% of the time):
|
0 1 2 3 4 5 6 7 |
patternUnits="userSpaceOnUse" width="20" height="20" ← tile size in user units (usually ≈ pixels) |
Example 1 – Classic polka dots pattern
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<svg width="400" height="300" style="border:1px solid #eee; background:#f9f9f9;"> <defs> <pattern id="dots" width="40" height="40" patternUnits="userSpaceOnUse"> <circle cx="10" cy="10" r="6" fill="#FF5722"/> <circle cx="30" cy="30" r="6" fill="#FF5722"/> </pattern> </defs> <rect x="40" y="40" width="320" height="220" fill="url(#dots)" stroke="#FF5722" stroke-width="2"/> <text x="200" y="160" font-size="38" text-anchor="middle" fill="#333"> Polka Dots! </text> </svg> |
Result: Repeating orange dots every 40×40 units.
Try changing:
- r=”4″ → smaller dots
- width=”60″ height=”30″ → rectangular spacing
- Add more circles in different colors
Example 2 – Diagonal stripes (very popular)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<svg width="500" height="200"> <defs> <pattern id="diagonalStripes" width="20" height="20" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="20" height="20" fill="#2196F3"/> <path d="M0,0 L20,20 M0,20 L20,0" stroke="#BBDEFB" stroke-width="4"/> </pattern> </defs> <rect x="50" y="50" width="400" height="100" fill="url(#diagonalStripes)" rx="12"/> </svg> |
Alternative cleaner way (only lines):
|
0 1 2 3 4 5 6 7 8 9 10 |
<pattern id="stripes" width="12" height="12" patternUnits="userSpaceOnUse"> <rect width="12" height="12" fill="#4CAF50"/> <line x1="0" y1="0" x2="12" y2="12" stroke="#C8E6C9" stroke-width="4"/> <line x1="0" y1="12" x2="12" y2="0" stroke="#C8E6C9" stroke-width="4"/> </pattern> |
Example 3 – Checkerboard pattern
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<svg width="400" height="300"> <defs> <pattern id="checker" width="40" height="40" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="20" height="20" fill="#673AB7"/> <rect x="20" y="20" width="20" height="20" fill="#673AB7"/> <rect x="20" y="0" width="20" height="20" fill="#D1C4E9"/> <rect x="0" y="20" width="20" height="20" fill="#D1C4E9"/> </pattern> </defs> <rect x="40" y="40" width="320" height="220" fill="url(#checker)"/> </svg> |
Example 4 – Pattern with text or small icon (creative!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<svg width="500" height="240"> <defs> <pattern id="hearts" width="60" height="60" patternUnits="userSpaceOnUse"> <path d="M30 15 C40 5, 50 15, 50 25 C50 35, 40 45, 30 55 C20 45, 10 35, 10 25 C10 15, 20 5, 30 15 Z" fill="#E91E63" transform="scale(0.6)"/> </pattern> </defs> <rect x="50" y="50" width="400" height="140" fill="url(#hearts)" rx="20"/> </svg> |
Quick Cheat Sheet – Pattern Units Decision
| Goal / Situation | Use this setting | Why? |
|---|---|---|
| Pattern size fixed (pixels) | patternUnits=”userSpaceOnUse” | Most common – predictable size |
| Pattern scales with shape size | patternUnits=”objectBoundingBox” | Width/height in 0–1 range (like gradients) |
| Content inside also scales with shape | patternContentUnits=”objectBoundingBox” | Rare – usually leave as userSpaceOnUse |
| Want rotated pattern | Add patternTransform=”rotate(45)” | Nice for diagonal stripes |
Common beginner mistakes
- Forget width & height → pattern invisible
- width=”0″ or very small → nothing or tiny repeated tile
- Use percentages without objectBoundingBox → unexpected size
- No fill/stroke inside pattern → transparent tiles
- Pattern too large → looks like solid color
Mini practice tasks
- Create a green grid pattern (thin black lines every 30 units)
- Make red diagonal candy-cane style stripes
- Design a pattern with small yellow stars repeating
Paste your code here if you want feedback — I’ll review it like we’re pair-programming together 😄
Patterns are incredibly powerful once you get comfortable — you can literally fill shapes with any repeating design you can draw in SVG.
Next we can cover repeating patterns with images (<image> inside pattern), animated patterns, or combining patterns with gradients/filters.
Any part confusing? Tile size? Units difference? Creating your own tiles? Just tell me — we’ll zoom in with more examples until it feels easy and fun! 🚀
