Skip to content
WebTricks

PS5-style animated gradient border button

A button with a conic-gradient border that rotates continuously, in the style of the PlayStation 5 UI.

  • button
  • gradient
  • animation
  • conic-gradient
  • @property
Corner radius12px
Spin speed3s
Border width3px
Button color#0b0b12
Text color#ffffff
Gradient color 1#00e5ff
Gradient color 2#7b5cff
Gradient color 3#ff3ea5
HTML
<button class="ps5-btn">Press Start</button>
CSS
: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 --angle registers the angle as an animatable custom property. Without @property, browsers can’t interpolate an <angle>, so the conic-gradient couldn’t be animated.
  • ::before paints a full conic-gradient and then a mask (mask-composite: exclude) punches out the center, leaving only a --border-w ring — that’s the glowing border.
  • ::after sits on top of the fill area with the button color, creating the inner “card” and the --gap between border and content.
  • The @keyframes animate --angle from 0deg to 360deg, 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 @property at-rule is supported in all modern evergreen browsers. The animation gracefully degrades to a static gradient border where it isn’t.