Most tab components you find out there ship kilobytes of JavaScript for something the browser already knows how to do: manage a selected state across several options. That is, quite literally, a group of radio buttons.

The idea

Each tab is a <label> tied to a hidden <input type="radio">. When the radio is checked, CSS reacts and reveals the matching panel. Zero JS, and as a bonus you get arrow-key navigation for free, since radio groups bring that out of the box.

<label for="tab1">Tab 1</label>
<input id="tab1" name="tabs" type="radio" class="sr-only peer" checked />

The trick: :has()

The panel restyles based on whether its sibling input is checked:

label:has(+ input:checked) {
  color: white;
  background: var(--primary);
}

:has(+ input:checked) reads as “this label that has, right after it, a checked input”. It’s CSS looking forward.

Real accessibility

Since the input stays focusable (sr-only, not display:none), the keyboard works. Just remember to add a visible focus ring:

label:has(+ input:focus-visible) {
  outline: 2px solid var(--primary);
}

Takeaway

Before reaching for a library, ask whether the browser already solves the problem. Here, one <input> and a modern selector save you the entire runtime.