Use this skill when creating gradient borders on elements using the pseudo-element mask technique or border-image approach in CSS.
Techniques for applying gradient colors to element borders using pseudo-element masking or the border-image property.
border-radiusThis is the most flexible approach and supports border-radius. The technique works by:
position: relative::before pseudo-element with position: absolute that covers the element plus the desired border widthbackgroundmask with two layers and to punch out the center, leaving only the border visiblemask-composite: excludeThe mask uses two overlapping linear-gradient(white, white) layers:
By compositing these with mask-composite: exclude (or -webkit-mask-composite: xor), the center is removed and only the border ring of the gradient remains.
The border-image property can apply a gradient directly:
border-image: linear-gradient(to right, #ff0080, #7928ca) 1;
This is simpler but does not work with border-radius — the corners will remain square.
A card with a smooth rainbow gradient border that supports rounded corners.
<div class="rainbow-border-card">
<div class="card-content">
<h2>Gradient Border</h2>
<p>This card has a rainbow gradient border with rounded corners.</p>
</div>
</div>
/* ── Rainbow border card ───────────────────────── */
.rainbow-border-card {
position: relative;
border-radius: 16px;
padding: 2px; /* This becomes the visible border width */
background: linear-gradient(
135deg,
#ff0080,
#ff8c00,
#40e0d0,
#7928ca,
#ff0080
);
}
.rainbow-border-card .card-content {
background: #0f0f0f;
border-radius: 14px; /* parent radius minus padding */
padding: 24px;
color: #ffffff;
}
Note: This "padding as border" technique is the simplest gradient border method that supports
border-radius. The parent carries the gradient background; the inner element covers the center with a solid background.
The full pseudo-element mask approach for cases where the inner background must be transparent or complex.
<div class="gradient-border-mask">
<h2>Masked Gradient Border</h2>
<p>Uses mask-composite to show only the border.</p>
</div>
/* ── Gradient border via mask ──────────────────── */
.gradient-border-mask {
--border-width: 2px;
--border-radius: 16px;
position: relative;
border-radius: var(--border-radius);
padding: 24px;
color: #ffffff;
background: #1a1a2e;
}
.gradient-border-mask::before {
content: "";
position: absolute;
inset: calc(-1 * var(--border-width));
border-radius: calc(var(--border-radius) + var(--border-width));
background: linear-gradient(135deg, #667eea, #764ba2);
z-index: -1;
/* Mask: cut out the center to leave only the border */
mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
padding: var(--border-width);
}
A rotating gradient border using @property for hue animation.
<div class="animated-gradient-border">
<div class="card-inner">
<h2>Animated Border</h2>
<p>The gradient rotates around the border continuously.</p>
</div>
</div>
/* ── Animated gradient border ──────────────────── */
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
.animated-gradient-border {
position: relative;
border-radius: 16px;
padding: 2px;
background: conic-gradient(
from var(--gradient-angle),
#ff0080,
#ff8c00,
#40e0d0,
#7928ca,
#ff0080
);
animation: border-rotate 3s linear infinite;
}
.animated-gradient-border .card-inner {
background: #0f0f0f;
border-radius: 14px;
padding: 24px;
color: #fff;
}
@keyframes border-rotate {
to {
--gradient-angle: 360deg;
}
}
A soft, low-contrast gradient for understated UI elements.
/* ── Subtle gradient border ────────────────────── */
.subtle-gradient-border {
position: relative;
border-radius: 12px;
padding: 1px;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0.15),
rgba(255, 255, 255, 0.05)
);
}
.subtle-gradient-border .inner {
background: #1c1c1e;
border-radius: 11px;
padding: 20px;
color: #e0e0e0;
}
The simplest method, but incompatible with rounded corners.
/* ── border-image gradient (square corners only) ─ */
.border-image-gradient {
border: 3px solid;
border-image: linear-gradient(to right, #12c2e9, #c471ed, #f64f59) 1;
padding: 24px;
color: #ffffff;
background: #111;
}
mask-composite browser prefixes — Standard CSS uses mask-composite: exclude while WebKit browsers require -webkit-mask-composite: xor. Always include both:
mask-composite: exclude;
-webkit-mask-composite: xor;
Forgetting position: relative — The pseudo-element is absolutely positioned—without a relative parent, it will escape the element's bounds.
Border-radius mismatch — When using the padding technique, the inner element's border-radius must be the parent's radius minus the padding. Otherwise the inner corners will peek out or not align.
z-index: -1 on pseudo-element — The ::before gradient layer should sit behind the content. If the parent has a z-index or stacking context that prevents this, restructure with an explicit inner wrapper.
border-image kills border-radius — The border-image property overrides border-radius entirely. If rounded corners are needed, use the padding or mask technique instead.
Transparent backgrounds — If the element's background is transparent, the padding approach will show the gradient through the center. Use the mask technique instead.
@property support — The @property rule for animating CSS custom properties is not supported in Firefox (as of early 2025). Provide a fallback or use JavaScript-driven animation for cross-browser animated borders.
-webkit-mask-composite: xor and -webkit-mask shorthand behavior.@property for smooth hue or angle transitions. Fall back to a static gradient when @property is unsupported.box-shadow for glow effects — add a colored box-shadow that matches the gradient's dominant hue for extra depth.border.