Skip to the page
TACTILE UI

Kit part · Navigation · Tabs

Tabs

Views of the same thing, switched in place: keys in a tray, the chosen view a raised cap.

Element
role="tablist"
Needs
kit.css + kit.mjs
Rules
tabs.rules.md · 3
Finishes
Aluminium · Graphite · Porcelain · Black
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts
01

Variants

Two tabs
Five tabs
02

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

Aluminium

PartChosenHoverFocus
Tabs

Graphite

PartChosenHoverFocus
Tabs
03

API

NameKindValuesWhat it does
.tui-tabsclassrole="tablist"A tray of tabs. Wider than its container, it scrolls inside itself, never the page.
role="tab" · aria-selectedattributeon <button>The chosen tab is a raised cap.
aria-controlsattributepanel idwireTabs shows that panel and hides the others.
wireTabs(list)functionkit.mjsSelection, roving tabindex, arrows. Runs on every tablist when kit.mjs is imported.
tui-tabeventdetail: the tabFired on the tablist when a tab is chosen; bubbles.
Left/Right · Home/Endkeyboard—Move and select, wrapping at the ends.
04

Markup

<div class="tui-tabs" role="tablist" aria-label="Range">
  <button role="tab" aria-selected="true" aria-controls="p-day" id="t-day">Day</button>
  <button role="tab" aria-controls="p-week" id="t-week">Week</button>
</div>
<div role="tabpanel" id="p-day" aria-labelledby="t-day">…</div>
<div role="tabpanel" id="p-week" aria-labelledby="t-week" hidden>…</div>
import { wireTabs } from '/kit/kit.mjs';
// Importing kit.mjs wires every .tui-tabs already on the page.
// For tabs you add later:
wireTabs(document.querySelector('#my-tabs'));
document.addEventListener('tui-tab', (e) => console.log(e.detail.id));

Needs kit.css and kit.mjs. How to install the kit.

05

Accessibility

  • The WAI-ARIA tabs pattern: one Tab stop for the list, arrows inside it, panels linked by aria-controls and aria-labelledby.
  • Selection follows focus, which suits views that render at once.
06

How it’s built

A tray with transparent buttons; the chosen one gets a raised face and a small shadow. wireTabs is thirty lines in kit.mjs: it sets aria-selected, the roving tabindex and each panel’s hidden.

07

Rules

tabs.rules.mdIn the brain

Tabs are for views; a selector is for settings. Two to five tabs.

3 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

08

Selector

One mode of two to five: latching keys in a tray, one down at a time, each with a lamp that lights when chosen.

Side rail

App navigation in a panel: the current page is a recess with its lamp lit. The rail on the left of this page is one.

Quiet

Bar

The top of a page: a wordmark with a lamp, printed links, and one contrast key at most.

Docs
Finish
Volume