タブ
componentタブで表示する内容を切り替えて、多くの情報を整理して見せるためのパーツです。
solid × state
isSelected: false / true × enable / hover / focus / disabled
line × state
isSelected: false / true × enable / hover / focus / disabled (count 表示は line variant のみ)
使用例 — solid
クリックで isSelected をトグル(兄弟同士の選択を排他にする JS は data-tabgroup で対応)
使用例 — line (with count)
タブ右側に件数バッジ。tab-count 要素を含めるだけ
機能
このコンポーネントの用途
同じ領域で表示内容を切り替えるディスクロージャー。情報を一度に出しすぎない。
URL を持たない同一画面内で、表示する中身(詳細内の補助情報、別の観点のパネル等)を切り替える。
同じ内容の見え方だけを変える切替(一覧 / グリッド、並び順等)は toggle-btn-group。
一覧を「すべて / 有望 / 休眠 …」のような 1 つの軸で切り替える単一選択の絞り込み
(1 つ選ぶと他が外れる。件数付き)も tab(tabs-line + tab-count)。複数同時に選べる
絞り込みは filter-chip、フォームの入力値としての単一選択は radio / select。
手続きの進捗は stepper、ページ送りは pagination、サイト移動は menu(サイドナビ)。
使用法
推奨される使い方と、やりがちな NG パターン
OK
- ✓role="tablist" / role="tab"、選択は aria-selected="true"。
- ✓variant は solid / line から選ぶ。
- ✓幅が足りないときは段落ちに任せる(.tabs が自動で折り返す)。
- ✓単一選択の絞り込み切替では、切り替わる一覧の領域を tabpanel にし、件数は tab-count (line variant)で示す。
NG
- ✕tablist を overflow-x-auto 等で包んで横スクロールにしない → 隠れたタブに気付けないため段落ちさせる。
- ✕複数同時に選べる絞り込みに使わない → filter-chip(aria-pressed の独立トグル)。
- ✕同じ内容の見え方(一覧 / グリッド 等)の切替に使わない → toggle-btn-group(tabpanel が要らない切替)。
- ✕ページ遷移リンクの並びに使わない → 同一ページ内の表示切替に使う。
- ✕設定画面のセクション(プロフィール / 通知 / セキュリティ等)のような、独立した画面の 粒度を持つ切替に使わない → 各セクションをページにして menu でナビする(フォームを持つ・ 単独で開けるべき・現在地を URL で示せるべきセクションはページ + menu)。 ※ tab はボタン状の切替 UI(リンクに見えない見た目)のため、「テキストリンクは常に下線」原則の例外として下線なし。
- ✕選択状態をクラスだけで示さない → aria-selected を使う。
タブのアクセシビリティ
DS はタブの見た目を提供します。WAI-ARIA のタブパターン(role・矢印キー・パネル関連付け)はプロダクト側で実装します。WCAG 2.2 全基準は アクセシビリティ ページを参照。
期待される配慮
Presentation / Adaptability / Interaction / Assistive Technology
選択タブは色+下線/背景で示す(line は下線+色、solid は背景+文字色)。件数バッジはラベルに併記。
文字は rem / トークンで拡大に追従。タブが多い時は横スクロールで逃がす。
Tab でタブ列に入り、←→ でタブ移動(roving tabindex)。フォーカスリングが出る。
role="tablist/tab/tabpanel"、選択は aria-selected、タブとパネルを aria-controls/aria-labelledby で結ぶ。
DS が担保する機能
追加実装なしで満たされる
- ✓選択状態を
aria-selectedで表す設計(色+下線/背景の二重表現) - ✓キーボードフォーカスリング(
:focus-visible・info/500 の 3px リング) - ✓選択タブの文字色・背景は AAA コントラスト(primary/700)
- ✓
disabledは opacity+cursor-not-allowed(色は維持)
実装時の必須対応
プロダクト側で担保する
- !
role="tablist"/role="tab"/role="tabpanel"を付け、選択タブだけaria-selected="true" - !タブ→パネルを
aria-controls、パネル→タブをaria-labelledbyで結ぶ - !矢印キー移動(roving tabindex: 選択タブ
tabindex="0"/他-1)を実装 - !ページ遷移には使わない(遷移は
menu/link)
テスト方法
キーボード / スクリーンリーダー / 自動チェック
| キー | 動作 |
|---|---|
| Tab | タブ列へ出入りする(列内は 1 タブストップ) |
| ← → | タブを移動する |
| Enter / Space | タブを選択しパネルを切り替える |
- SR「タブ、選択済み、n/m」とラベルが読まれ、対応するパネルへ移動できる
- 自動axe / Lighthouse で role 構造・
aria-selected・パネル関連付けを確認
選択タブは aria-selected="true"(1つだけ)
達成基準:WCAG 4.1.2 名前・役割・値
選択タブだけ aria-selected="true"。SR に選択が伝わる。
<button role="tab" aria-selected="true">すべて</button> <button role="tab" aria-selected="false">未読</button>
role/aria-selected が無いと、ただのボタンの並びで選択状態が伝わらない。
<button class="tab tab-line">すべて</button> <!-- role/aria-selected なし -->