Articles

CSS clip-path and Masking Explained

clip-path and mask-image clip or fade elements into custom shapes in pure CSS, replacing image editors and SVG sprites for cropping.

Takina Takina · · 4 min read
Close-up of CSS code on a screen

clip-path and mask-image are CSS properties that cut or fade an element down to a custom shape, entirely in the stylesheet. No image editor, no SVG sprite sheet, no extra wrapper element required. clip-path gives you a hard-edged boundary — anything outside the shape simply isn’t painted. mask-image is more flexible: it can produce soft, gradient edges by using the alpha channel or luminance of an image, gradient, or SVG as a stencil.

clip-path: hard-edged shapes

clip-path accepts a handful of basic shape functions, each defining a region relative to the element’s box:

.badge {
  clip-path: circle(50% at center);
}

.ribbon {
  clip-path: polygon(0 0, 100% 0, 100% 75%, 50% 100%, 0 75%);
}

.card {
  clip-path: inset(10px 20px 10px 20px round 8px);
}
  • circle(radius at position) — a circular clip, useful for avatars or spotlight reveals.
  • ellipse(rx ry at position) — an elliptical variant.
  • inset(top right bottom left round radius) — trims edges inward, optionally with rounded corners.
  • polygon(x1 y1, x2 y2, ...) — an arbitrary straight-edged shape, defined as a list of coordinate pairs. This is how you get angled banners, chevrons, and diagonal section dividers without a background image.

Everything outside the shape is clipped away — it doesn’t just become invisible, it stops taking up interactive space too, so clicks and hovers outside the shape pass through to whatever’s behind it.

Referencing an SVG <clipPath>

For shapes more complex than the basic functions allow, point clip-path at an SVG clipPath element by URL:

<svg width="0" height="0">
  <clipPath id="blob" clipPathUnits="objectBoundingBox">
    <path d="M0.5,0 C0.8,0 1,0.2 1,0.5 ..." />
  </clipPath>
</svg>
.hero-image {
  clip-path: url(#blob);
}

This is the escape hatch for organic, hand-drawn blob shapes — common in marketing hero sections — that would be painful to express as a polygon().

mask-image: soft edges

Where clip-path gives you a binary in-or-out boundary, mask-image uses the mask source’s alpha (or luminance) as a gradient of visibility. A linear-gradient mask is the classic use case: fading an image or block of text into transparency at one edge.

.fade-out {
  mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}

Fully opaque areas of the mask show the element at full opacity; fully transparent areas hide it completely; everything in between blends smoothly. You can also mask with a PNG, an SVG, or radial-gradient() for vignette-style effects.

Multiple mask layers can be combined with mask-composite, similar to how background-image supports layered backgrounds — useful for combining a shape mask with a gradient fade in one declaration.

clip-path vs mask-image

clip-pathmask-image
Edge qualityHard, geometricCan be soft or gradient
SourceBasic shapes, SVG clipPath, URLImages, gradients, SVG
PerformanceCheap — geometry onlySlightly heavier — image compositing
Hit testingClipped area is non-interactiveMasked-out area is still hidden, but historically less consistent across browsers for pointer events
Typical useBadges, banners, angled dividersFades, vignettes, image cutouts

Reach for clip-path when you need a crisp geometric boundary and want the cheapest possible paint cost. Reach for mask-image when the edge itself needs to fade or follow a raster/vector image rather than a simple polygon.

Animating clip-path

Because clip-path describes a shape as a list of numeric values, browsers can interpolate between two shapes of the same type and point count to animate the transition:

.reveal {
  clip-path: circle(0% at 50% 50%);
  transition: clip-path 0.4s ease-out;
}

.reveal.is-open {
  clip-path: circle(150% at 50% 50%);
}

This produces a smooth circular reveal without JavaScript-driven layout changes — a common pattern for image galleries and modal transitions, and a nice complement to the View Transitions API when you want a shaped wipe rather than a plain cross-fade. Animating polygon() shapes works the same way, as long as both keyframes list the same number of points; browsers can’t interpolate between shapes with a different point count.

Both properties are cheaper to animate than changing width, height, or clip: rect() (the old, deprecated clipping property), because they don’t trigger layout — only compositing. That makes them a good fit alongside other layout-friendly techniques covered in our Core Web Vitals guide.

Combining with container queries and grid

clip-path shapes defined in percentages scale naturally with the element’s box, which pairs well with responsive layouts built on CSS Grid or sized with container queries — the clip recalculates automatically as the container resizes, with no extra media-query bookkeeping.

Browser support and fallbacks

Both properties have solid support in current evergreen browsers for the basic shape functions and gradient masks; SVG-referenced clip paths and layered masks are the parts most likely to need a fallback check on older engines. Because a missing clip-path or mask-image simply degrades to “no clipping” rather than broken layout, both are safe to use progressively — design the unclipped state to look acceptable on its own, then layer the shape on top.

The takeaway

clip-path cuts an element to a hard-edged shape — circles, polygons, insets, or an SVG path — cheaply and with animatable geometry. mask-image fades an element using the alpha or luminance of a gradient, image, or SVG, which is what you want for soft edges and vignettes. Both skip the need for pre-cropped image assets, and both animate on the compositor rather than triggering layout, making them a low-cost way to add shaped reveals and transitions to a page.

Takina Takina · · 4 min read

CSS object-fit and object-position, Explained

object-fit controls how an image or video is cropped inside its box, and object-position controls which part of it stays visible. How they work together.

#CSS #Web Development #Frontend
Takina Takina · · 5 min read

CSS inherit, initial, unset & revert Explained

CSS's four global keywords control where a property's value comes from. How inherit, initial, unset, and revert differ, with a comparison table.

#CSS #Web Development #Frontend
Takina Takina · · 4 min read

Dynamic Viewport Units: dvh, svh, and lvh Explained

dvh, svh, and lvh fix the classic mobile vh bug where browser toolbars cut off full-height layouts. Here's what each unit measures and when to use it.

#CSS #Web Development #Frontend