SVG Clip and Mask
clipPath cuts a shape to a hard-edged silhouette while mask uses grayscale and alpha values to reveal content with soft, partial transparency.
Two Ways to Hide Part of a Shape
clipPath and mask both let you show only part of an SVG element, but they answer different questions. clipPath asks 'is this pixel inside or outside the clip shape?' - a strict yes-or-no boundary. mask asks 'how visible should this pixel be?' - driven by the luminance or alpha of whatever you draw inside the mask, which means masks can produce soft, gradient, or partially transparent edges that clipPath cannot.
clipPath: Hard-Edged Cropping
Define a <clipPath> with a unique id containing one or more shapes, then reference it from any element with clip-path="url(#id)". Only the geometry of the shapes inside <clipPath> matters - their fill, stroke, and opacity are ignored. Anything outside the clip shape's outline is simply not rendered.
Example
<!DOCTYPE html>
<html>
<body>
<svg viewBox="0 0 120 120">
<clipPath id="circleClip">
<circle cx="60" cy="60" r="45" />
</clipPath>
<rect x="0" y="0" width="120" height="120" fill="#f39c12"
clip-path="url(#circleClip)" />
</svg>
</body>
</html>mask: Soft, Graduated Visibility
A <mask> contains shapes or gradients whose luminance controls opacity in the masked element: white areas show through fully, black areas hide completely, and every shade of gray in between produces partial transparency. Reference a mask with mask="url(#id)" the same way you reference a clip path. This makes <mask> the tool of choice for fade-outs, vignettes, and soft-edged reveals.
Example
<!DOCTYPE html>
<html>
<body>
<svg viewBox="0 0 120 120">
<defs>
<linearGradient id="fade" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="white" />
<stop offset="1" stop-color="black" />
</linearGradient>
<mask id="fadeMask">
<rect x="0" y="0" width="120" height="120" fill="url(#fade)" />
</mask>
</defs>
<rect x="0" y="0" width="120" height="120" fill="#8e44ad"
mask="url(#fadeMask)" />
</svg>
</body>
</html>Combining clipPath and mask
You can apply both a clip-path and a mask to the same element, or nest a masked group inside a clipped one. A common pattern is using clipPath to establish a hard outer boundary (like a rounded-rectangle frame) and mask to fade the content near the edges inside that boundary.
Example
<!DOCTYPE html>
<html>
<body>
<svg viewBox="0 0 120 120">
<defs>
<clipPath id="frame">
<rect x="10" y="10" width="100" height="100" rx="12" />
</clipPath>
<radialGradient id="vignette">
<stop offset="0.6" stop-color="white" />
<stop offset="1" stop-color="black" />
</radialGradient>
<mask id="vignetteMask">
<rect x="0" y="0" width="120" height="120" fill="url(#vignette)" />
</mask>
</defs>
<g clip-path="url(#frame)">
<rect x="0" y="0" width="120" height="120" fill="#16a085"
mask="url(#vignetteMask)" />
</g>
</svg>
</body>
</html>- clipPath shapes ignore fill and stroke - only their outline geometry is used.
- mask supports full color and gradients, and both luminance and alpha channels affect the result.
- Browsers typically render clip-path faster than mask because it needs no offscreen compositing buffer.
- clipPathUnits and maskUnits can be set to objectBoundingBox to make the clip or mask scale with the target element automatically.
- A masked element with mask-type="alpha" uses the mask content's opacity instead of its luminance to determine visibility.
Exercise: SVG Clip and Mask
What is the fundamental difference between clip-path and mask in SVG?