Chapter 26: SVG Clipping and Masking
SVG: Clipping and Masking!
These two techniques let you hide parts of shapes, text, images, or groups in very creative ways — basically, they are SVG’s version of “cookie cutters” and “photo masks” (like in Photoshop or Figma).
I’m going to explain everything slowly and clearly, like we’re sitting together building examples step by step.
First — What is the big difference between Clipping and Masking?
| Feature | Clipping (<clipPath>) | Masking (<mask>) |
|---|---|---|
| What it does | Completely shows or hides parts (hard cut) | Fades / partially shows parts using grayscale + alpha |
| Uses transparency? | No — it’s all-or-nothing (binary) | Yes — black = hidden, white = fully visible, gray = partial |
| Best for | Sharp, clean cutouts (circles, stars, text shapes) | Soft edges, vignettes, gradients of visibility, glows |
| Color of defining shape | Color doesn’t matter — only the shape/outline counts | Brightness + alpha matters (white = visible, black = hidden) |
| Common real-world use | Circular avatars, text knockouts, irregular frames | Feathered edges, spotlights, faded borders, duotone |
| Performance | Usually faster (simpler) | Slightly heavier (handles alpha) |
Both are defined in <defs> and applied with the clip-path or mask attribute.
1. Clipping with <clipPath>
A <clipPath> defines a clipping region — anything inside the clipPath is visible, anything outside is hidden (hard cut, no feathering).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<svg width="400" height="300"> <defs> <clipPath id="circleClip"> <circle cx="200" cy="150" r="100"/> </clipPath> </defs> <image href="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=800" x="0" y="0" width="400" height="300" clip-path="url(#circleClip)" /> </svg> |
→ The photo is perfectly clipped to a circle — very common for profile pictures / avatars.
Example 2 – Clipping with text (knockout / text mask effect)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<svg width="500" height="200" style="background:#0D47A1;"> <defs> <clipPath id="textClip"> <text x="250" y="130" font-size="110" font-weight="bold" text-anchor="middle" font-family="Arial Black"> SVG </text> </clipPath> </defs> <rect width="100%" height="100%" fill="#2196F3" clip-path="url(#textClip)"/> <text x="250" y="130" font-size="110" font-weight="bold" text-anchor="middle" fill="white"> SVG </text> </svg> |
→ The blue rectangle is only visible where the word “SVG” is — very clean text-shaped background.
Example 3 – Clipping a group (multiple elements)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<svg width="320" height="320"> <defs> <clipPath id="starClip"> <polygon points="160,40 190,120 270,120 205,170 230,250 160,200 90,250 115,170 50,120 130,120"/> </clipPath> </defs> <g clip-path="url(#starClip)"> <image href="https://images.unsplash.com/photo-1517849845537-4d257902454a?w=600" x="0" y="0" width="320" height="320"/> </g> </svg> |
→ Photo is clipped to a star shape — very nice for creative icons/badges.
2. Masking with <mask>
A <mask> uses luminance (brightness) + alpha to decide visibility:
- White / fully opaque = fully visible
- Black / fully transparent = fully hidden
- Gray / semi-transparent = partially visible (fade)
- You can use gradients, blurs, images, etc. inside the mask
|
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"> <defs> <mask id="softMask"> <rect width="100%" height="100%" fill="black"/> <!-- start fully hidden --> <circle cx="200" cy="150" r="120" fill="white"/> <!-- white circle = visible area --> </mask> </defs> <image href="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=800" x="0" y="0" width="400" height="300" mask="url(#softMask)" /> </svg> |
→ Hard circular cutout (because white circle has sharp edge)
Example 5 – Soft / feathered mask (real power of masking)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<svg width="400" height="300"> <defs> <mask id="featherMask"> <rect width="100%" height="100%" fill="black"/> <circle cx="200" cy="150" r="140" fill="white"> <!-- Add blur for soft edge --> <feGaussianBlur stdDeviation="20"/> </circle> </mask> </defs> <image href="https://images.unsplash.com/photo-1517849845537-4d257902454a?w=600" x="0" y="0" width="400" height="300" mask="url(#featherMask)" /> </svg> |
→ Now the circle has soft, feathered edges — very nice vignette / spotlight effect.
Example 6 – Gradient mask (fade to transparent)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<svg width="500" height="200"> <defs> <mask id="fadeMask"> <rect width="100%" height="100%" fill="white"/> <rect x="0" y="0" width="100%" height="100%"> <linearGradient id="fadeGrad"> <stop offset="0%" stop-color="white"/> <stop offset="100%" stop-color="black"/> </linearGradient> <feFlood flood-color="url(#fadeGrad)"/> </rect> </mask> </defs> <image href="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=800" x="0" y="0" width="500" height="200" mask="url(#fadeMask)" /> </svg> |
→ Photo fades from full visibility (left) to completely hidden (right).
Quick Comparison Table (2025–2026 perspective)
| You want… | Use this | Why / When to choose |
|---|---|---|
| Sharp / hard-edged cutout | <clipPath> | Cleaner, faster, no partial transparency |
| Soft / feathered / faded edges | <mask> | Only masking can do smooth transitions |
| Text-shaped image / knockout | <clipPath> with <text> | Very sharp & readable |
| Vignette / spotlight / glow fade | <mask> with blurred circle | Natural soft transition |
| Complex gradient visibility | <mask> with gradient | <clipPath> cannot do partial transparency |
Common beginner mistakes
- Forget url(#id) → no effect
- Put <clipPath> or <mask> outside <defs> → ignored
- Use color in <clipPath> → color is ignored (only shape matters)
- Apply clip-path to group but children overflow → still clipped
- Mask with no white areas → entire element disappears
- Small <mask> or <clipPath> size → effect too tiny
Mini practice tasks
- Clip a photo to a rounded rectangle (use <rect rx=”…”> inside <clipPath>)
- Create a soft circular vignette mask on any image
- Make text that “reveals” a colorful gradient background only where letters are
Paste your code here if you want feedback — I’ll review it like we’re pair-programming together 😄
Clipping and masking are where SVG starts to feel like a real graphic design tool — once you master them, you can create avatars, badges, creative text effects, vignettes, and much more.
Next we can go into advanced clipping (multiple paths, text + shapes), animated masks, or combining clip + mask + filters.
Which part feels most confusing or exciting? Hard vs soft edges? Text clipping? Feathered masks? Just tell me — we’ll zoom in with more examples until it’s super clear and fun! 🚀
