18 CSS Radio Button Designs
A CSS radio button is a styled mutually-exclusive form control — pick one option from a set. These 18 hand-coded designs cover every common interaction style: classic concentric pulse, sliding pill toggles, magnetic orbs that glide between options, ink-drop fills, star bursts, tilt cards, segmented bars, neon rings, pricing tiers with featured ribbons, and glow pulses. Every demo wraps a real native input type=radio (kept visually hidden but focusable) with a custom indicator, so keyboard, screen-reader, and form-submission semantics all work out of the box. 100% pure CSS — no JavaScript required.
18 hand-coded CSS radio buttons — pill slider, magnetic orb, ink drop, star burst, segmented bar, neon ring, pricing tier, glow pulse and more. Every demo is unique, accessible, and copy-paste ready.
.crb-pulse { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-pulse label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-pulse input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-pulse span {
width: 18px; height: 18px; border-radius: 50%;
border: 2px solid #444461; background: transparent;
position: relative; transition: border-color 0.2s;
}
.crb-pulse span::after {
content: ''; position: absolute; inset: 3px;
border-radius: 50%; background: #7c6cff;
transform: scale(0); transition: transform 0.4s cubic-bezier(0.34,1.56,0.64,1);
}
.crb-pulse input:checked + span { border-color: #7c6cff; }
.crb-pulse input:checked + span::after { transform: scale(1); animation: crb-pulse-burst 0.5s ease-out; }
@keyframes crb-pulse-burst {
0% { box-shadow: 0 0 0 0 rgba(124,108,255,0.6); }
100% { box-shadow: 0 0 0 12px rgba(124,108,255,0); }
} <fieldset class="crb-pulse"> <legend class="crb-sr">Plan</legend> <label><input type="radio" name="crb-pulse" checked /><span></span>Starter</label> <label><input type="radio" name="crb-pulse" /><span></span>Pro</label> <label><input type="radio" name="crb-pulse" /><span></span>Team</label> </fieldset>
.crb-pill {
display: inline-flex; position: relative; padding: 4px;
background: #1a1a28; border: 1px solid rgba(255,255,255,0.08);
border-radius: 999px;
}
.crb-pill input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-pill label {
flex: 1 1 0; min-width: 80px;
position: relative; z-index: 1;
padding: 8px 16px;
font: 600 12px/1 system-ui, sans-serif; color: #9d9bbf;
text-align: center;
cursor: pointer; transition: color 0.25s;
border-radius: 999px;
}
.crb-pill input:checked + label { color: #fff; }
.crb-pill-thumb {
position: absolute; top: 4px; bottom: 4px; left: 4px;
width: calc(33.333% - 2.667px);
background: linear-gradient(135deg, #7c6cff, #a78bfa);
border-radius: 999px; z-index: 0;
transition: transform 0.4s cubic-bezier(0.65,0,0.35,1);
}
#crb-pill-2:checked ~ .crb-pill-thumb { transform: translateX(100%); }
#crb-pill-3:checked ~ .crb-pill-thumb { transform: translateX(200%); } <fieldset class="crb-pill"> <legend class="crb-sr">Billing</legend> <input type="radio" name="crb-pill" id="crb-pill-1" checked /> <label for="crb-pill-1">Monthly</label> <input type="radio" name="crb-pill" id="crb-pill-2" /> <label for="crb-pill-2">Yearly</label> <input type="radio" name="crb-pill" id="crb-pill-3" /> <label for="crb-pill-3">Forever</label> <span class="crb-pill-thumb"></span> </fieldset>
.crb-orb { display: flex; flex-direction: column; gap: 8px; border: 0; padding: 0; }
.crb-orb input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-orb label {
display: flex; align-items: center; gap: 12px;
padding: 8px 14px; border-radius: 8px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
transition: background 0.25s, color 0.25s;
}
.crb-orb-dot {
width: 14px; height: 14px; border-radius: 50%;
background: #2a2a3e; box-shadow: inset 0 0 0 2px #444461;
transition: background 0.35s cubic-bezier(0.65,0,0.35,1), box-shadow 0.35s, transform 0.35s;
}
.crb-orb input:checked + label { background: rgba(124,108,255,0.08); color: #fff; }
.crb-orb input:checked + label .crb-orb-dot {
background: #7c6cff; box-shadow: inset 0 0 0 2px #7c6cff, 0 0 12px rgba(124,108,255,0.7);
transform: scale(1.15);
} <fieldset class="crb-orb"> <legend class="crb-sr">Speed</legend> <input type="radio" name="crb-orb" id="crb-orb-1" checked /> <label for="crb-orb-1"><span class="crb-orb-dot"></span>Slow</label> <input type="radio" name="crb-orb" id="crb-orb-2" /> <label for="crb-orb-2"><span class="crb-orb-dot"></span>Fast</label> <input type="radio" name="crb-orb" id="crb-orb-3" /> <label for="crb-orb-3"><span class="crb-orb-dot"></span>Turbo</label> </fieldset>
.crb-ink { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-ink label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-ink input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-ink span {
width: 18px; height: 18px; border-radius: 50%;
border: 2px solid #444461; background: transparent;
position: relative; overflow: hidden;
transition: border-color 0.25s;
}
.crb-ink span::before {
content: ''; position: absolute; inset: 0;
background: linear-gradient(180deg, #06b6d4, #0ea5e9);
transform: translateY(-100%);
transition: transform 0.5s cubic-bezier(0.65,0,0.35,1);
}
.crb-ink input:checked + span { border-color: #06b6d4; }
.crb-ink input:checked + span::before { transform: translateY(0); } <fieldset class="crb-ink"> <legend class="crb-sr">Theme</legend> <label><input type="radio" name="crb-ink" /><span></span>Light</label> <label><input type="radio" name="crb-ink" checked /><span></span>Dark</label> <label><input type="radio" name="crb-ink" /><span></span>Auto</label> </fieldset>
.crb-star { display: flex; flex-direction: column; gap: 8px; border: 0; padding: 0; }
.crb-star label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-star input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-star svg {
width: 22px; height: 22px;
fill: transparent;
stroke: #444461; stroke-width: 1.5;
transition: stroke 0.3s, fill 0.4s;
}
.crb-star input:checked + svg {
stroke: #f5a623; fill: #f5a623;
filter: drop-shadow(0 0 6px rgba(245,166,35,0.5));
animation: crb-star-draw 0.6s ease-out;
}
@keyframes crb-star-draw {
0% { stroke-dasharray: 60; stroke-dashoffset: 60; fill: transparent; }
60% { stroke-dasharray: 60; stroke-dashoffset: 0; fill: transparent; }
100% { stroke-dasharray: 60; stroke-dashoffset: 0; fill: #f5a623; }
} <fieldset class="crb-star"> <legend class="crb-sr">Priority</legend> <label><input type="radio" name="crb-star" /><svg viewBox="0 0 24 24" aria-hidden="true"><polygon points="12,2 15,9 22,9 17,14 19,21 12,17 5,21 7,14 2,9 9,9"/></svg>Low</label> <label><input type="radio" name="crb-star" checked /><svg viewBox="0 0 24 24" aria-hidden="true"><polygon points="12,2 15,9 22,9 17,14 19,21 12,17 5,21 7,14 2,9 9,9"/></svg>Medium</label> <label><input type="radio" name="crb-star" /><svg viewBox="0 0 24 24" aria-hidden="true"><polygon points="12,2 15,9 22,9 17,14 19,21 12,17 5,21 7,14 2,9 9,9"/></svg>High</label> </fieldset>
.crb-tilt { display: flex; gap: 8px; border: 0; padding: 0; }
.crb-tilt input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-tilt label {
flex: 1; display: flex; flex-direction: column; gap: 4px;
padding: 12px 10px; border-radius: 10px;
background: #1a1a28; border: 1px solid rgba(255,255,255,0.06);
cursor: pointer;
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.3s, border-color 0.3s, background 0.3s;
}
.crb-tilt label strong {
font: 700 13px/1 system-ui, sans-serif; color: #fff;
}
.crb-tilt label em {
font: 500 11px/1 monospace; color: #9d9bbf; font-style: normal;
}
.crb-tilt label:has(input:checked) {
transform: translateY(-4px) rotate(-1deg);
background: linear-gradient(135deg, rgba(124,108,255,0.18), rgba(167,139,250,0.1));
border-color: rgba(124,108,255,0.5);
box-shadow: 0 8px 24px rgba(124,108,255,0.3);
} <fieldset class="crb-tilt"> <legend class="crb-sr">Choose plan</legend> <label><input type="radio" name="crb-tilt" /><strong>Solo</strong><em>$9/mo</em></label> <label><input type="radio" name="crb-tilt" checked /><strong>Team</strong><em>$29/mo</em></label> <label><input type="radio" name="crb-tilt" /><strong>Scale</strong><em>$99/mo</em></label> </fieldset>
.crb-tick { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-tick label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-tick input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-tick span {
width: 18px; height: 18px; border-radius: 50%;
border: 2px solid #444461; background: transparent;
position: relative;
transition: border-color 0.2s, background 0.3s;
}
.crb-tick span::after {
content: ''; position: absolute;
top: 50%; left: 50%;
width: 4px; height: 8px;
border: solid #fff; border-width: 0 2px 2px 0;
transform: translate(-50%, -60%) rotate(45deg) scale(0);
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1);
}
.crb-tick input:checked + span { background: #2ecc8a; border-color: #2ecc8a; }
.crb-tick input:checked + span::after { transform: translate(-50%, -60%) rotate(45deg) scale(1); } <fieldset class="crb-tick"> <legend class="crb-sr">Layout</legend> <label><input type="radio" name="crb-tick" checked /><span></span>Compact</label> <label><input type="radio" name="crb-tick" /><span></span>Comfortable</label> <label><input type="radio" name="crb-tick" /><span></span>Spacious</label> </fieldset>
.crb-swatch { display: flex; gap: 10px; border: 0; padding: 0; }
.crb-swatch input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-swatch label { cursor: pointer; }
.crb-swatch span {
display: block;
width: 32px; height: 32px; border-radius: 50%;
background: var(--c);
box-shadow: inset 0 0 0 0 #15151d, 0 0 0 0 var(--c);
transition: box-shadow 0.3s, transform 0.25s cubic-bezier(0.34,1.56,0.64,1);
}
.crb-swatch label:hover span { transform: scale(1.08); }
.crb-swatch input:checked + span {
box-shadow: inset 0 0 0 4px #15151d, 0 0 0 2px var(--c), 0 0 16px var(--c);
transform: scale(1.12);
} <fieldset class="crb-swatch"> <legend class="crb-sr">Colour</legend> <label style="--c:#7c6cff"><input type="radio" name="crb-swatch" /><span></span></label> <label style="--c:#ff6c8a"><input type="radio" name="crb-swatch" checked /><span></span></label> <label style="--c:#2ecc8a"><input type="radio" name="crb-swatch" /><span></span></label> <label style="--c:#f5a623"><input type="radio" name="crb-swatch" /><span></span></label> <label style="--c:#06b6d4"><input type="radio" name="crb-swatch" /><span></span></label> </fieldset>
.crb-seg {
display: inline-flex; position: relative;
padding: 3px; background: #0c0c12;
border: 1px solid rgba(255,255,255,0.06); border-radius: 8px;
}
.crb-seg input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-seg label {
flex: 1 1 0; min-width: 64px;
position: relative; z-index: 1;
padding: 7px 14px;
font: 600 12px/1 system-ui, sans-serif; color: #9d9bbf;
text-align: center;
cursor: pointer; transition: color 0.25s;
border-radius: 6px;
}
.crb-seg input:checked + label { color: #fff; }
.crb-seg-thumb {
position: absolute; top: 3px; bottom: 3px; left: 3px;
width: calc(25% - 1.5px);
background: #1f1f2e; border: 1px solid rgba(124,108,255,0.4);
border-radius: 6px; z-index: 0;
box-shadow: 0 2px 8px rgba(0,0,0,0.4);
transition: transform 0.35s cubic-bezier(0.65,0,0.35,1);
}
#crb-seg-2:checked ~ .crb-seg-thumb { transform: translateX(100%); }
#crb-seg-3:checked ~ .crb-seg-thumb { transform: translateX(200%); }
#crb-seg-4:checked ~ .crb-seg-thumb { transform: translateX(300%); } <fieldset class="crb-seg"> <legend class="crb-sr">View</legend> <input type="radio" name="crb-seg" id="crb-seg-1" checked /> <label for="crb-seg-1">Day</label> <input type="radio" name="crb-seg" id="crb-seg-2" /> <label for="crb-seg-2">Week</label> <input type="radio" name="crb-seg" id="crb-seg-3" /> <label for="crb-seg-3">Month</label> <input type="radio" name="crb-seg" id="crb-seg-4" /> <label for="crb-seg-4">Year</label> <span class="crb-seg-thumb"></span> </fieldset>
.crb-neon { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-neon label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 monospace; color: #9d9bbf; cursor: pointer;
}
.crb-neon input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-neon span {
width: 16px; height: 16px; border-radius: 50%;
border: 1.5px solid #2a4a3a; background: transparent;
position: relative;
transition: border-color 0.25s, box-shadow 0.3s;
}
.crb-neon span::after {
content: ''; position: absolute; inset: 3px;
border-radius: 50%; background: #2ecc8a;
opacity: 0; transform: scale(0.4);
transition: opacity 0.25s, transform 0.3s;
}
.crb-neon input:checked + span {
border-color: #2ecc8a;
box-shadow: 0 0 12px rgba(46,204,138,0.6), inset 0 0 6px rgba(46,204,138,0.3);
}
.crb-neon input:checked + span::after {
opacity: 1; transform: scale(1);
box-shadow: 0 0 6px #2ecc8a;
} <fieldset class="crb-neon"> <legend class="crb-sr">Mode</legend> <label><input type="radio" name="crb-neon" /><span></span>Idle</label> <label><input type="radio" name="crb-neon" checked /><span></span>Active</label> <label><input type="radio" name="crb-neon" /><span></span>Burst</label> </fieldset>
.crb-tier { display: flex; gap: 10px; border: 0; padding: 14px 0 0; }
.crb-tier input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-tier label { flex: 1; cursor: pointer; }
.crb-tier-card {
display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
position: relative;
padding: 12px;
background: #1a1a28; border: 1.5px solid rgba(255,255,255,0.06); border-radius: 10px;
transition: border-color 0.3s, background 0.3s;
}
.crb-tier-card strong { font: 700 14px/1 system-ui, sans-serif; color: #fff; }
.crb-tier-card em { font: 600 12px/1 monospace; color: #a78bfa; font-style: normal; }
.crb-tier-ribbon {
position: absolute;
top: 0; left: 50%;
padding: 4px 12px;
border-radius: 999px;
font: 700 9px/1 system-ui, sans-serif;
text-transform: uppercase;
text-align: center;
white-space: nowrap;
background: linear-gradient(90deg, #7c6cff, #ff6c8a); color: #fff;
box-shadow: 0 2px 8px rgba(124,108,255,0.4);
opacity: 0;
transform: translate(-50%, -50%) scale(0.6);
transition: opacity 0.25s, transform 0.35s cubic-bezier(0.34,1.56,0.64,1);
pointer-events: none;
}
.crb-tier input:checked + .crb-tier-card {
border-color: #7c6cff;
background: linear-gradient(135deg, rgba(124,108,255,0.15), rgba(255,108,138,0.05));
}
.crb-tier input:checked + .crb-tier-card .crb-tier-ribbon {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
} <fieldset class="crb-tier">
<legend class="crb-sr">Plan tier</legend>
<label>
<input type="radio" name="crb-tier" />
<span class="crb-tier-card">
<strong>Basic</strong>
<em>$5/mo</em>
<span class="crb-tier-ribbon">Best value</span>
</span>
</label>
<label>
<input type="radio" name="crb-tier" checked />
<span class="crb-tier-card">
<strong>Plus</strong>
<em>$15/mo</em>
<span class="crb-tier-ribbon">Best value</span>
</span>
</label>
</fieldset> .crb-wave { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-wave label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-wave input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-wave span {
width: 20px; height: 20px; border-radius: 50%;
border: 2px solid #444461;
position: relative; overflow: hidden;
background: transparent;
transition: border-color 0.25s;
}
.crb-wave span::before {
content: ''; position: absolute;
top: 100%; left: -50%; width: 200%; height: 200%;
background: radial-gradient(ellipse at top, transparent 40%, #06b6d4 41%);
transition: top 0.5s ease-out;
}
.crb-wave input:checked + span { border-color: #06b6d4; }
.crb-wave input:checked + span::before {
top: -10%;
animation: crb-wave-bob 1.4s ease-in-out infinite;
}
@keyframes crb-wave-bob {
0%,100% { transform: translateY(0); }
50% { transform: translateY(-2px); }
} <fieldset class="crb-wave"> <legend class="crb-sr">Volume</legend> <label><input type="radio" name="crb-wave" /><span></span>Low</label> <label><input type="radio" name="crb-wave" checked /><span></span>Mid</label> <label><input type="radio" name="crb-wave" /><span></span>Loud</label> </fieldset>
.crb-clip { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-clip label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 monospace; color: #cbd5e1; cursor: pointer;
}
.crb-clip input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-clip span {
width: 18px; height: 18px; border-radius: 50%;
border: 2px solid #444461;
position: relative; overflow: hidden;
transition: border-color 0.25s;
}
.crb-clip span::after {
content: ''; position: absolute; inset: 3px;
border-radius: 50%;
background: linear-gradient(135deg, #ff6c8a, #f5a623);
clip-path: polygon(50% 50%, 50% 50%, 50% 50%);
transition: clip-path 0.5s cubic-bezier(0.65,0,0.35,1);
}
.crb-clip input:checked + span { border-color: #ff6c8a; }
.crb-clip input:checked + span::after {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
} <fieldset class="crb-clip"> <legend class="crb-sr">Speed</legend> <label><input type="radio" name="crb-clip" /><span></span>0.5x</label> <label><input type="radio" name="crb-clip" /><span></span>1x</label> <label><input type="radio" name="crb-clip" checked /><span></span>2x</label> </fieldset>
.crb-grad { display: flex; gap: 8px; border: 0; padding: 0; }
.crb-grad input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-grad label { cursor: pointer; }
.crb-grad-card {
display: block; padding: 10px 18px;
background: #1a1a28; border-radius: 8px;
font: 600 12px/1 system-ui, sans-serif; color: #9d9bbf;
position: relative; isolation: isolate;
transition: color 0.25s;
}
.crb-grad-card::before {
content: ''; position: absolute; inset: -2px; border-radius: 10px;
background: conic-gradient(from 0deg, #7c6cff, #ff6c8a, #f5a623, #2ecc8a, #06b6d4, #7c6cff);
z-index: -1; opacity: 0;
animation: crb-grad-spin 4s linear infinite;
transition: opacity 0.3s;
}
.crb-grad-card::after {
content: ''; position: absolute; inset: 0; border-radius: 8px;
background: #1a1a28; z-index: -1;
}
.crb-grad input:checked + .crb-grad-card { color: #fff; }
.crb-grad input:checked + .crb-grad-card::before { opacity: 1; }
@keyframes crb-grad-spin { to { transform: rotate(360deg); } } <fieldset class="crb-grad"> <legend class="crb-sr">Tier</legend> <label><input type="radio" name="crb-grad" /><span class="crb-grad-card">Bronze</span></label> <label><input type="radio" name="crb-grad" /><span class="crb-grad-card">Silver</span></label> <label><input type="radio" name="crb-grad" checked /><span class="crb-grad-card">Gold</span></label> </fieldset>
.crb-avatar { display: flex; gap: 10px; border: 0; padding: 0; }
.crb-avatar input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-avatar label { cursor: pointer; }
.crb-avatar span {
display: flex; align-items: center; justify-content: center;
width: 40px; height: 40px; border-radius: 50%;
background: linear-gradient(135deg, var(--c), color-mix(in srgb, var(--c), white 30%));
font: 700 14px/1 system-ui, sans-serif; color: #fff;
box-shadow: 0 0 0 0 var(--c);
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.3s, opacity 0.25s;
opacity: 0.55;
}
.crb-avatar label:hover span { opacity: 0.85; }
.crb-avatar input:checked + span {
opacity: 1; transform: scale(1.15);
box-shadow: 0 0 0 3px #15151d, 0 0 0 5px var(--c), 0 0 18px var(--c);
} <fieldset class="crb-avatar"> <legend class="crb-sr">Avatar</legend> <label style="--c:#7c6cff"><input type="radio" name="crb-avatar" /><span>A</span></label> <label style="--c:#ff6c8a"><input type="radio" name="crb-avatar" checked /><span>B</span></label> <label style="--c:#2ecc8a"><input type="radio" name="crb-avatar" /><span>C</span></label> <label style="--c:#f5a623"><input type="radio" name="crb-avatar" /><span>D</span></label> </fieldset>
.crb-stack {
display: flex; flex-direction: column;
position: relative; padding-left: 12px;
border: 0; border-left: 2px solid rgba(255,255,255,0.06);
}
.crb-stack input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-stack label {
display: flex; flex-direction: column; gap: 2px;
padding: 8px 10px; border-radius: 6px;
cursor: pointer; transition: color 0.25s, background 0.25s;
}
.crb-stack label strong {
font: 600 13px/1 system-ui, sans-serif; color: #cbd5e1;
}
.crb-stack label em {
font: 500 11px/1 system-ui, sans-serif; color: #6b6987; font-style: normal;
}
.crb-stack input:checked + label strong { color: #fff; }
.crb-stack input:checked + label { background: rgba(124,108,255,0.06); }
.crb-stack-rail {
position: absolute; left: -2px; top: 0;
width: 2px; height: 33.333%;
background: linear-gradient(180deg, #7c6cff, #a78bfa);
border-radius: 2px;
transition: transform 0.4s cubic-bezier(0.65,0,0.35,1);
}
#crb-stack-2:checked ~ .crb-stack-rail { transform: translateY(100%); }
#crb-stack-3:checked ~ .crb-stack-rail { transform: translateY(200%); } <fieldset class="crb-stack"> <legend class="crb-sr">Notifications</legend> <input type="radio" name="crb-stack" id="crb-stack-1" checked /> <label for="crb-stack-1"><strong>All</strong><em>Every update</em></label> <input type="radio" name="crb-stack" id="crb-stack-2" /> <label for="crb-stack-2"><strong>Important</strong><em>Critical only</em></label> <input type="radio" name="crb-stack" id="crb-stack-3" /> <label for="crb-stack-3"><strong>Off</strong><em>Silent mode</em></label> <span class="crb-stack-rail"></span> </fieldset>
.crb-push { display: flex; gap: 8px; border: 0; padding: 0; }
.crb-push input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-push label { cursor: pointer; }
.crb-push span {
display: block; padding: 10px 18px;
background: linear-gradient(180deg, #2a2a3e, #1a1a28);
color: #cbd5e1; font: 600 12px/1 system-ui, sans-serif;
border-radius: 8px;
box-shadow: 0 3px 0 #0c0c12, inset 0 1px 0 rgba(255,255,255,0.06);
transform: translateY(0);
transition: transform 0.12s, box-shadow 0.12s, color 0.2s, background 0.25s;
}
.crb-push input:checked + span {
transform: translateY(3px);
background: linear-gradient(180deg, #1a1a28, #0c0c12);
color: #a78bfa;
box-shadow: 0 0 0 #0c0c12, inset 0 2px 6px rgba(0,0,0,0.5), inset 0 0 0 1px rgba(124,108,255,0.3);
} <fieldset class="crb-push"> <legend class="crb-sr">Difficulty</legend> <label><input type="radio" name="crb-push" /><span>Easy</span></label> <label><input type="radio" name="crb-push" checked /><span>Hard</span></label> <label><input type="radio" name="crb-push" /><span>Expert</span></label> </fieldset>
.crb-glow { display: flex; flex-direction: column; gap: 10px; border: 0; padding: 0; }
.crb-glow label {
display: flex; align-items: center; gap: 10px;
font: 500 13px/1 system-ui, sans-serif; color: #cbd5e1; cursor: pointer;
}
.crb-glow input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.crb-glow span {
width: 18px; height: 18px; border-radius: 50%;
border: 2px solid #444461; background: transparent;
position: relative;
transition: border-color 0.2s, background 0.25s;
}
.crb-glow span::after {
content: ''; position: absolute; inset: -2px;
border-radius: 50%;
box-shadow: 0 0 0 0 rgba(255,108,138,0.7);
pointer-events: none;
}
.crb-glow input:checked + span {
background: linear-gradient(135deg, #ff6c8a, #a78bfa);
border-color: transparent;
}
.crb-glow input:checked + span::after {
animation: crb-glow-ripple 0.9s ease-out;
}
@keyframes crb-glow-ripple {
0% { box-shadow: 0 0 0 0 rgba(255,108,138,0.7), 0 0 0 0 rgba(167,139,250,0.5); }
60% { box-shadow: 0 0 0 14px rgba(255,108,138,0), 0 0 0 22px rgba(167,139,250,0); }
100% { box-shadow: 0 0 0 14px rgba(255,108,138,0), 0 0 0 22px rgba(167,139,250,0); }
} <fieldset class="crb-glow"> <legend class="crb-sr">Reaction</legend> <label><input type="radio" name="crb-glow" /><span></span>Like</label> <label><input type="radio" name="crb-glow" /><span></span>Love</label> <label><input type="radio" name="crb-glow" /><span></span>Celebrate</label> </fieldset>
Frequently asked questions
How do I style a radio button with CSS?
Are these custom radio buttons accessible?
Do I need JavaScript to make these radio buttons work?
What's the difference between a radio button and a checkbox?
Can I use these in any framework?
Related collections
22 CSS Button Group Designs
22 hand-coded CSS button group designs — segmented pill, connected outline, filter chips, split action, toggle, pagination, stepper wizard, view switcher, FAB, brutalist, glass, neon, date range, approve / reject, icon toolbar, dropdown combo, action group, number stepper, tab nav, aurora drift. Semantic HTML, accessible, copy-paste ready.
31 CSS Buttons
31 hand-coded CSS buttons — gradients, glassmorphism, 3D press, neon glow, ripple, glitch, shimmer, rainbow border and more. Pure CSS, copy-paste ready.
20 CSS Cards with Animations
20 hand-crafted CSS card components — aurora glow, 3D tilt, glassmorphism, neon borders, flip card, pricing, terminal, music player, weather widget and more.