PS5-style animated gradient border button
A button with a conic-gradient border that rotates continuously, in the style of the PlayStation 5 UI.
Corner radius12px
Spin speed3s
Border width3px
Button color#0b0b12
Text color#ffffff
Gradient color 1#00e5ff
Gradient color 2#7b5cff
Gradient color 3#ff3ea5
<button class="ps5-btn">Press Start</button> :root {
--border-w: 3px;
--gap: 3px;
--r: 12px;
--speed: 3s;
--btn-bg: #0b0b12;
--btn-text: #ffffff;
--c1: #00e5ff;
--c2: #7b5cff;
--c3: #ff3ea5;
}
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.ps5-btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 16px 36px;
border: none;
border-radius: var(--r);
background: transparent;
color: var(--btn-text);
font-size: 15px;
font-weight: 500;
letter-spacing: 0.02em;
cursor: pointer;
isolation: isolate;
-webkit-tap-highlight-color: transparent;
box-shadow: 0 0 0 transparent;
transition: box-shadow 300ms ease;
}
.ps5-btn::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: var(--border-w);
background: conic-gradient(
from var(--angle),
var(--c1), var(--c2), var(--c3), var(--c1)
);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
animation: ps5-spin var(--speed) linear infinite;
transition: filter 0.3s ease;
}
.ps5-btn::after {
content: '';
position: absolute;
inset: calc(var(--border-w) + var(--gap));
border-radius: calc(var(--r) - var(--border-w) - var(--gap));
background: var(--btn-bg);
z-index: -1;
}
.ps5-btn:hover::before { filter: blur(0.4px) brightness(1.25); }
.ps5-btn:hover { box-shadow: 0 0 24px -6px var(--c2); }
@keyframes ps5-spin {
to { --angle: 360deg; }
} How it works
The rotating border is a single pseudo-element trick, no SVG or extra markup:
@property --angleregisters the angle as an animatable custom property. Without@property, browsers can’t interpolate an<angle>, so theconic-gradientcouldn’t be animated.::beforepaints a fullconic-gradientand then a mask (mask-composite: exclude) punches out the center, leaving only a--border-wring — that’s the glowing border.::aftersits on top of the fill area with the button color, creating the inner “card” and the--gapbetween border and content.- The
@keyframesanimate--anglefrom0degto360deg, spinning the gradient.
Customize
Use the controls above — everything is driven by the custom properties in :root: --speed for rotation, --border-w / --gap for thickness, --r for corners, --btn-bg / --btn-text for the surface, and --c1…--c3 for the gradient palette. Hit Copy CSS with your settings to grab your tuned version.
Browser support: the
@propertyat-rule is supported in all modern evergreen browsers. The animation gracefully degrades to a static gradient border where it isn’t.