Wormhole Tabs
Tab nav where the active indicator stretches into a trailing wormhole as it moves between tabs — implemented via :has() and a single shared pseudo-element with smooth width interpolation.
Wormhole Tabs the 21st 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-worm" role="tablist" aria-label="Settings sections"> <legend class="cbgp-sr">Settings sections</legend> <input type="radio" name="cbgp-worm" id="cbgp-worm-1" checked /> <label for="cbgp-worm-1"><span>Profile</span></label> <input type="radio" name="cbgp-worm" id="cbgp-worm-2" /> <label for="cbgp-worm-2"><span>Notifications</span></label> <input type="radio" name="cbgp-worm" id="cbgp-worm-3" /> <label for="cbgp-worm-3"><span>Privacy</span></label> <input type="radio" name="cbgp-worm" id="cbgp-worm-4" /> <label for="cbgp-worm-4"><span>Billing</span></label> </fieldset>
.cbgp-worm {
display: grid;
grid-template-columns: repeat(4, 1fr);
position: relative;
border: 0; padding: 0 0 10px;
width: 100%; max-width: 460px;
border-bottom: 1px solid rgba(255,255,255,0.08);
}
.cbgp-worm input { appearance: none; -webkit-appearance: none; position: absolute; opacity: 0; }
.cbgp-worm label {
padding: 12px 8px 14px;
font: 700 11px/1 ui-monospace, monospace;
letter-spacing: 0.18em;
text-transform: uppercase;
color: rgba(220,225,230,0.5);
cursor: pointer;
position: relative;
text-align: center;
transition: color 0.25s;
}
.cbgp-worm label::after {
content: '';
position: absolute;
left: 50%; bottom: -1px;
width: 0; height: 3px;
transform: translateX(-50%);
background: linear-gradient(90deg, transparent, #00ffe0 30%, #ff5af1 70%, transparent);
border-radius: 2px;
transition: width 0.5s cubic-bezier(.65,0,.35,1);
box-shadow: 0 0 14px rgba(0,255,224,0.6);
}
.cbgp-worm label:hover { color: rgba(220,225,230,0.85); }
.cbgp-worm input:checked + label { color: #fff; }
.cbgp-worm input:checked + label::after { width: 100%; }
.cbgp-worm input:focus-visible + label { outline: 2px solid #00ffe0; outline-offset: -2px; border-radius: 4px; }