Gradient borders with a mask
A masked pseudo-element keeps the radius and the inside see-through.
Paco Coursey@pacocourseyMixin for gradient borders
The post is a video; the demo rebuilds the technique.
1 · Border over a pattern
Drag width and radius. Watch the inner corner and the stripes.
Two boxesBad
Pro planUnlimited projects and a quiet border.
padding: 1pxSolid insideMasked ::beforeGood
Pro planUnlimited projects and a quiet border.
mask-composite: excludeSee-through.card { position: relative; border-radius: 16px; }
.card::before {
content: ""; position: absolute; inset: 0;
border-radius: inherit;
padding: 1px; /* border width */
background: linear-gradient(135deg, #f43f5e, #8b5cf6, #06b6d4);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
pointer-events: none;
}
Why it matters, pros and cons
Why it matters
The mask cuts the padding box out of the border box, so only the ring is painted and the inside stays clear.
Pros
- The card keeps its own background, or none, so patterns and images show through.
- Radius is inherited, so the inner curve stays concentric at any width.
- One pseudo-element and no wrapper: the markup does not change.
Cons
- Needs mask-composite; older browsers need the -webkit- pair as well.
- The pseudo-element is taken, so the card cannot use ::before for anything else.
- A gradient ring can't animate with transitions; use a custom property or a rotating layer.