Holographic Dial
Icon segmented control where the active icon is filled with a moving conic-gradient holographic sheen. Hover shifts the gradient phase before commit.
Holographic Dial the 8th of 22 designs in the 22 CSS Button Group Designs collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<fieldset class="cbgp-holo" role="group" aria-label="View mode">
<legend class="cbgp-sr">View mode</legend>
<input type="radio" name="cbgp-holo" id="cbgp-holo-1" checked />
<label for="cbgp-holo-1" aria-label="Grid view"
><svg viewBox="0 0 24 24" aria-hidden="true">
<rect x="3" y="3" width="7" height="7" />
<rect x="14" y="3" width="7" height="7" />
<rect x="3" y="14" width="7" height="7" />
<rect x="14" y="14" width="7" height="7" /></svg
></label>
<input type="radio" name="cbgp-holo" id="cbgp-holo-2" />
<label for="cbgp-holo-2" aria-label="List view"
><svg viewBox="0 0 24 24" aria-hidden="true">
<line x1="8" y1="6" x2="21" y2="6" />
<line x1="8" y1="12" x2="21" y2="12" />
<line x1="8" y1="18" x2="21" y2="18" />
<circle cx="4" cy="6" r="1" />
<circle cx="4" cy="12" r="1" />
<circle cx="4" cy="18" r="1" /></svg
></label>
<input type="radio" name="cbgp-holo" id="cbgp-holo-3" />
<label for="cbgp-holo-3" aria-label="Card view"
><svg viewBox="0 0 24 24" aria-hidden="true">
<rect x="3" y="4" width="18" height="6" rx="1" />
<rect x="3" y="14" width="18" height="6" rx="1" /></svg
></label>
</fieldset> @property --cbgp-holo-a { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
.cbgp-holo {
display: inline-flex; gap: 0;
border: 1px solid rgba(255,255,255,0.06);
background: rgba(8,10,18,0.85);
border-radius: 10px;
overflow: hidden;
padding: 3px;
}
.cbgp-holo input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.cbgp-holo label {
--cbgp-holo-a: 0deg;
display: flex; align-items: center; justify-content: center;
width: 44px; height: 40px;
cursor: pointer;
border-radius: 8px;
background:
conic-gradient(from var(--cbgp-holo-a),
transparent 0deg, transparent 240deg,
rgba(0,255,224,0) 260deg, rgba(0,255,224,0.3) 290deg,
rgba(255,90,241,0.3) 320deg, rgba(255,90,241,0) 350deg,
transparent 360deg);
transition: --cbgp-holo-a 0.7s cubic-bezier(.65,0,.35,1), background 0.3s;
}
.cbgp-holo svg {
width: 16px; height: 16px;
fill: none; stroke: rgba(220,225,230,0.5);
stroke-width: 1.8; stroke-linecap: round;
transition: stroke 0.25s;
}
.cbgp-holo label:hover { --cbgp-holo-a: 180deg; }
.cbgp-holo label:hover svg { stroke: rgba(220,225,230,0.85); }
.cbgp-holo input:checked + label {
--cbgp-holo-a: 360deg;
background:
conic-gradient(from var(--cbgp-holo-a),
rgba(0,255,224,0.32), rgba(255,90,241,0.32),
rgba(255,200,80,0.28), rgba(0,255,224,0.32));
box-shadow: 0 0 14px rgba(0,255,224,0.18);
}
.cbgp-holo input:checked + label svg { stroke: #fff; }
.cbgp-holo input:focus-visible + label { outline: 2px solid #00ffe0; outline-offset: -2px; }