tabs
The one pattern the platform still can't do accessibly without script. m-tabs enhances working markup — it never renders it.
Examples
Default
Account settings panel.
Password panel. Try the arrow keys — roving tabindex, automatic activation.
Team panel.
Underline
Overall leaders.
Attacking leaders.
Passing leaders.
Defending leaders.
Goalkeeping leaders.
Basic usage
<m-tabs variant="underline">
<nav aria-label="Leader category">
<button>Overall</button>
<button selected>Attacking</button> <!-- optional initial -->
</nav>
<section>…overall panel…</section>
<section>…attacking panel…</section>
</m-tabs>
<script type="module" src="mica/tabs.js"></script>
API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
variant | underline | segmented | Uses the quieter underline treatment without changing behavior. |
selected | boolean on a tab button | first tab | Chooses the optional initial tab before enhancement. |
aria-controls | panel ID | positional pairing | Explicitly pairs a button with a panel. |
Content/markup contract
| Part | Contract | Default | Description |
|---|---|---|---|
nav | direct child | required | Contains tab buttons. |
button | inside nav | required | Pairs positionally with a direct panel unless aria-controls names one. |
section | direct child | required | Panel content. Keep all content complete and readable without enhancement. |
tabs.js
Optional enhancement that registers m-tabs. It wires tablist, tab, and tabpanel roles; aria-selected; roving tabindex; Arrow Left/Right, Home, and End keys with automatic activation; selected-tab reveal; and position-aware overflow markers.
<script type="module" src="mica/tabs.js"></script>
Without the module, the nav is inert and every panel renders in order: complete, readable content rather than a CSS-only fake.
Accessibility
The module establishes native ARIA tabs semantics, labels each panel from its button, makes panels focusable, and manages keyboard focus and selection. The unenhanced fallback exposes every panel in document order.
Horizontal overflow
Tab labels never wrap. When the rail is narrower than its tabs, the nav scrolls horizontally with contained overscroll. With tabs.js, a direction marker fades in only on a side with more tabs, and selecting a partially visible tab brings it fully into view. The scrollbar stays hidden, but touch, wheel, and keyboard scrolling still work.
The rail is constrained to 20rem; tabs keep their intrinsic width and overflow scrolls.
Attacking leaders.
Passing leaders.
Defending leaders.
Goalkeeping leaders.
Use tabs for in-page panels. Route navigation and deep links should remain ordinary anchors outside m-tabs, so URLs, open-in-new-tab behavior, and routing stay consumer-owned.