Skip to content

CSS

A tab picker is a native radio group wearing the tab strip’s visual — a <fieldset> of <input type="radio"> sharing one name — so single-select, group labelling, and arrow-key roving all come from the browser, with no JS and no ARIA. It reuses Tabs.tng-tabs / .tng-tabs-item classes rather than shipping its own: the design is identical, and only the nested markup differs.

Wrap each radio in a .tng-tabs-item <label>. The styleguide keys the selected, disabled, and focus looks off the nested radio (:has(input:checked) / :has(input:disabled) / :has(input:focus-visible)) and visually hides the radio itself — so the markup needs no extra classes and no consumer CSS. The design has no visible group label, but the <fieldset> still needs a <legend> for its accessible name, so hide it with sr-only. The .tng-stack fieldset keeps the strip sized to its content.

Reach for it with a small set of mutually exclusive values (up to five); for content-switching navigation use Tabs instead.

<fieldset class="tng-stack">
<legend class="sr-only">Battery</legend>
<div class="tng-tabs">
<label class="tng-tabs-item">
<input type="radio" name="battery" value="50" />
50 KWH
</label>
<label class="tng-tabs-item">
<input type="radio" name="battery" value="75" checked />
75 KWH
</label>
<label class="tng-tabs-item">
<input type="radio" name="battery" value="90" />
90 KWH
</label>
</div>
</fieldset>
Battery

Add .is-ev to each option to switch the selected option’s border to the EV accent. Use it only on EV-tools surfaces.

<fieldset class="tng-stack">
<legend class="sr-only">Battery</legend>
<div class="tng-tabs">
<label class="tng-tabs-item is-ev">
<input type="radio" name="battery-ev" value="50" />
50 KWH
</label>
<label class="tng-tabs-item is-ev">
<input type="radio" name="battery-ev" value="75" checked />
75 KWH
</label>
<label class="tng-tabs-item is-ev">
<input type="radio" name="battery-ev" value="90" />
90 KWH
</label>
</div>
</fieldset>
Battery

The checked radio is the selection — mark it with the native checked attribute. There is no .is-selected class to keep in sync, because .tng-tabs-item:has(input:checked) reads the state straight off the radio.

<label class="tng-tabs-item">
<input type="radio" name="selected-demo" value="75" checked />
Selected option
</label>

Disable the nested radio, not the label. .tng-tabs-item:has(input:disabled) picks up the disabled look, and the browser keeps the option out of the group’s arrow-key roving.

<label class="tng-tabs-item">
<input type="radio" name="disabled-demo" value="90" disabled />
Disabled
</label>
<label class="tng-tabs-item is-ev">
<input type="radio" name="disabled-demo" value="100" disabled />
Disabled EV
</label>