Use clip-path for Edges and mask for Fades

clip-path and mask can both hide pixels, but they describe different jobs. A clip asks whether a point is inside a path. A mask can also say how visible that point should be.

My short rule is: use clip-path for a hard edge and mask for a fade.

A clip has a boundary

.photo {
  clip-path: circle(50%);
}

Everything inside the circle is shown and everything outside it is clipped. For an ordinary round photo, border-radius: 50% is even simpler.

Polygons are a more convincing use:

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

The boundary remains sharp. There is no partly visible area between the card and the space around it.

A mask can fade

.photo {
  mask-image: linear-gradient(
    black 70%,
    transparent
  );
}

The transition contains pixels at several alpha levels, which clip-path cannot describe. This works well when a photo should dissolve into its background or the edges of a scrolling list need a hint.

Masks are also handy for one-colour external icons:

.icon {
  width: 1.5rem;
  height: 1.5rem;
  color: blue;
  background: currentColor;
  mask: url("/icon.svg") center / contain no-repeat;
}

The image controls visibility and currentColor supplies the paint.

Both features stop at the paint stage

Clipping and masking do not reshape surrounding layout. An element keeps its original box, and an interactive area may not behave exactly like the visible outline suggests.

Test buttons, links, pointer targets, and focus indicators. I mainly use both properties for decoration because a rectangular fallback is easy to keep usable.

Choose the smaller explanation

Use border-radius for an ordinary circle, clip-path for a hard custom outline, and mask when transparency is part of the effect. Both features can involve SVG, but a complex SVG mask is not an upgrade if a five-point polygon already describes the design.

The easiest CSS to maintain is the one whose property matches the sentence you use to explain it.