18 CSS Play / Pause Button Designs
Gradient Disc
A `@property`-animated conic gradient rim that rotates while playing — true CSS angle animation, not a keyframes hack. Feels like a turntable or a high-end audio interface dial.
Gradient Disc the 10th of 18 designs in the 18 CSS Play / Pause Button Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<button class="pp-disc" type="button" aria-pressed="false" aria-label="Play" data-pp>
<span class="pp-disc-rim" aria-hidden="true"></span>
<span class="pp-disc-core" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
<path class="pp-disc-icon" d="M8 5 L8 19 L19 12 Z" fill="currentColor" />
</svg>
</span>
</button> @property --pp-disc-angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.pp-disc {
position: relative;
width: 64px;
height: 64px;
background: transparent;
border: 0;
padding: 0;
cursor: pointer;
border-radius: 50%;
}
.pp-disc:focus-visible {
outline: 3px solid rgba(192, 132, 252, 0.5);
outline-offset: 3px;
}
.pp-disc-rim {
position: absolute;
inset: 0;
border-radius: 50%;
background: conic-gradient(
from var(--pp-disc-angle, 0deg),
#c084fc,
#f472b6,
#fbbf24,
#34d399,
#c084fc
);
filter: blur(0px);
transition: filter 0.2s;
}
.pp-disc[aria-pressed="true"] .pp-disc-rim {
animation: ppDiscSpin 4s linear infinite;
filter: blur(0.5px);
}
@keyframes ppDiscSpin {
to {
--pp-disc-angle: 360deg;
}
}
.pp-disc-core {
position: absolute;
inset: 4px;
display: grid;
place-items: center;
background: radial-gradient(circle at 30% 25%, #2a2a36 0%, #15151d 100%);
border-radius: 50%;
color: #f0eeff;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.pp-disc:hover .pp-disc-core {
color: #c4b5fd;
}
.pp-disc-icon {
transition: d 0.3s cubic-bezier(0.5, 0, 0.3, 1.2);
}
.pp-disc[aria-pressed="true"] .pp-disc-icon {
d: path("M7 5 H10 V19 H7 Z M14 5 H17 V19 H14 Z");
}
@media (prefers-reduced-motion: reduce) {
.pp-disc,
.pp-disc * {
animation: none !important;
}
}
// ── Drop this on every page where you render a play/pause button ──
// Toggles aria-pressed + aria-label on click. The CSS handles all visuals.
document.querySelectorAll('[data-pp]').forEach(function (btn) {
btn.addEventListener('click', function () {
var playing = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', String(!playing));
btn.setAttribute('aria-label', !playing ? 'Pause' : 'Play');
});
}); More from 18 CSS Play / Pause Button Designs
Magnetic HoverLiquid DropRipple on ClickCassette TapeLive BadgeMorph TriangleVinyl RecordEqualiser BarsSkip HubLiquid WavePulse HaloToggle Pill
View the full collection →