Radio Dial
Bakelite-cream dial with a brass pointer locked to OFF. Click toggles to ON: the pointer swings clockwise to the right tick mark and stays there until the next click.
Radio Dial the 36th of 43 designs in the 43 CSS 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="btn-radio" aria-pressed="false" aria-label="Toggle power"> <span class="btn-radio-tick btn-radio-tick-l" aria-hidden="true">OFF</span> <span class="btn-radio-tick btn-radio-tick-r" aria-hidden="true">ON</span> <span class="btn-radio-arrow" aria-hidden="true"></span> </button>
.btn-radio {
position: relative;
width: 124px; height: 64px;
border: 3px solid #1a1a1a;
border-bottom-width: 6px;
border-radius: 124px 124px 0 0 / 124px 124px 0 0;
background: radial-gradient(ellipse at 50% 90%, #f5ede0 0%, #d8c8a8 100%);
cursor: pointer;
overflow: hidden;
font-family: ui-serif, Georgia, serif;
font-size: 9px; font-weight: 800;
letter-spacing: 0.14em;
box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}
.btn-radio-tick {
position: absolute; bottom: 6px;
color: #5a4520;
transition: color 0.3s ease, font-weight 0.3s ease;
}
.btn-radio-tick-l { left: 14px; color: #a32424; }
.btn-radio-tick-r { right: 14px; }
.btn-radio[aria-pressed="true"] .btn-radio-tick-l { color: #5a4520; }
.btn-radio[aria-pressed="true"] .btn-radio-tick-r { color: #a32424; }
.btn-radio-arrow {
position: absolute;
bottom: 0; left: 50%;
width: 4px; height: 44px;
background: linear-gradient(180deg, #c9a15e 0%, #6a4520 100%);
border-radius: 2px 2px 0 0;
transform-origin: bottom center;
transform: translateX(-2px) rotate(-40deg);
transition: transform 0.55s cubic-bezier(.3,1.2,.3,1);
}
.btn-radio[aria-pressed="true"] .btn-radio-arrow {
transform: translateX(-2px) rotate(40deg);
} document.querySelectorAll('.btn-radio').forEach(function(btn) {
btn.addEventListener('click', function() {
var pressed = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', pressed ? 'false' : 'true');
});
});