The original radio buttons: chunky preset keys on an old car stereo. Pressing one sinks it and pops the others back up, its LED lights and the display rolls to the station.
Also known as: car radio buttons css, 3d pressed radio buttons, vintage push button radio.
<div class="rad-retro-radio-presets" role="radiogroup" aria-label="Station preset">
<div class="rad-retro-radio-presets-display" aria-hidden="true"><span>88.1</span><span>94.7</span><span>101.5</span><span>107.9</span></div>
<div class="rad-retro-radio-presets-keys">
<label><input type="radio" name="rad-retro-radio-presets" value="88.1" aria-label="Preset 1, 88.1" checked><span>1</span></label>
<label><input type="radio" name="rad-retro-radio-presets" value="94.7" aria-label="Preset 2, 94.7"><span>2</span></label>
<label><input type="radio" name="rad-retro-radio-presets" value="101.5" aria-label="Preset 3, 101.5"><span>3</span></label>
<label><input type="radio" name="rad-retro-radio-presets" value="107.9" aria-label="Preset 4, 107.9"><span>4</span></label>
</div>
</div>.rad-retro-radio-presets {
--c: var(--rad-color, #3b82f6);
font-size: var(--rad-size, 18px);
--i: 0;
display: inline-grid;
gap: 0.75em;
padding: 0.8em 0.8em 0.7em;
border-radius: 0.9em;
background: linear-gradient(#3d424a, #22262c);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 0.6em 1.2em -0.5em rgba(0, 0, 0, 0.55);
font-family: system-ui, sans-serif;
line-height: 1.2;
}
.rad-retro-radio-presets:has(label:nth-of-type(2) :checked) { --i: 1; }
.rad-retro-radio-presets:has(label:nth-of-type(3) :checked) { --i: 2; }
.rad-retro-radio-presets:has(label:nth-of-type(4) :checked) { --i: 3; }
.rad-retro-radio-presets-display {
position: relative;
height: 2.1em;
overflow: hidden;
border-radius: 0.4em;
background: #0d1411;
box-shadow: inset 0 0.12em 0.35em rgba(0, 0, 0, 0.7);
color: var(--c);
font: 700 1.2em/1.75em ui-monospace, SFMono-Regular, Menlo, monospace;
letter-spacing: 0.08em;
text-shadow: 0 0 0.45em color-mix(in srgb, var(--c) 80%, transparent);
}
.rad-retro-radio-presets-display::before {
content: "FM";
position: absolute;
left: 0.9em;
font-size: 0.55em;
line-height: 3.18em;
opacity: 0.75;
}
.rad-retro-radio-presets-display span {
display: block;
padding-right: 0.6em;
text-align: right;
transform: translateY(calc(var(--i) * -100%));
transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.rad-retro-radio-presets-keys {
display: flex;
gap: 0.45em;
padding-top: 0.35em;
}
.rad-retro-radio-presets label {
position: relative;
border-radius: 0.45em;
background: #968c75;
box-shadow: 0 0.15em 0.3em rgba(0, 0, 0, 0.55);
cursor: pointer;
}
.rad-retro-radio-presets input {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
margin: 0;
opacity: 0;
cursor: pointer;
z-index: 1;
}
.rad-retro-radio-presets input + span {
position: relative;
display: grid;
place-items: center;
width: 2.9em;
height: 2.3em;
border-radius: 0.45em;
background: linear-gradient(#f5f0e3, #d9d0bb);
box-shadow: inset 0 1px 0 #fff;
color: #45413a;
font-size: 1.05em;
font-weight: 800;
transform: translateY(-0.34em);
transition: transform 0.22s cubic-bezier(0.3, 1.8, 0.5, 1), filter 0.2s ease;
}
.rad-retro-radio-presets input + span::before {
content: "";
position: absolute;
top: 0.28em;
width: 0.9em;
height: 0.16em;
border-radius: 0.1em;
background: #b6ad97;
transition: background-color 0.2s ease, box-shadow 0.2s ease;
}
.rad-retro-radio-presets label:hover input:not(:checked) + span {
filter: brightness(1.04);
transform: translateY(-0.26em);
}
.rad-retro-radio-presets input:checked + span {
filter: brightness(0.93);
transform: translateY(-0.04em);
transition: transform 0.08s ease-in, filter 0.1s ease;
}
.rad-retro-radio-presets input:checked + span::before {
background: var(--c);
box-shadow: 0 0 0.35em var(--c);
}
.rad-retro-radio-presets input:focus-visible + span {
outline: 0.12em solid var(--c);
outline-offset: 0.18em;
}
@media (prefers-reduced-motion: reduce) {
.rad-retro-radio-presets, .rad-retro-radio-presets *, .rad-retro-radio-presets::before, .rad-retro-radio-presets::after, .rad-retro-radio-presets *::before, .rad-retro-radio-presets *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--rad-color on the element or a parent.
Currently previewing #3b82f6.--rad-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 18px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.