テーブル

component

列ごとの項目名を上に並べて、複数のデータを行で比較するテーブルです。1 件の詳細を縦に並べて見せるときはシンプルテーブルを使います。

基本

項目名の行(thead)が上、データ行(tbody)が下。値が無いセルは — を text-fg-middle で表示(10.35:1、WCAG AAA)

Item Name Description Component Optional
1 Container コンテナ要素 —
2 Header ヘッダー要素 —
3 Body ボディ要素 —

使用例 — td 内に任意の UI

セルにはバッジやリンク、ボタンも入れられる

案件名 ステータス 担当者 詳細
Aプロジェクト 公開中 山田 太郎 詳細を見る(Aプロジェクト)
Bプロジェクト 審査中 佐藤 花子 詳細を見る(Bプロジェクト)
Cプロジェクト 下書き — 詳細を見る(Cプロジェクト)

列幅 — 締める列だけ指定し、自由文に余白を渡す

固定書式の列(日付・状態・金額・操作)は data-table-fit(数値は data-table-num)を th と同列の td 全てに付けて内容幅に締める。自由文は data-table-text の 1 列。列が多く収まらないときは data-table-wrap(tabindex="0")で包んで横スクロール — 列幅を詰めて無理に収めない

契約一覧
契約名 概要 金額 更新日 状態 操作
本社ビル賃貸借契約 本社ビル 3〜5 階の賃貸借。更新は 2 年ごとで、次回更新時に面積の見直しを予定。 1,200,000円 2026/09/01 有効 詳細を見る(本社ビル賃貸借契約)
清掃業務委託契約 共用部の日常清掃と月 1 回の定期清掃。 85,000円 2026/03/31 期限切れ 詳細を見る(清掃業務委託契約)
会計ソフト利用契約 クラウド会計の年間ライセンス。5 ユーザーまで。 96,000円 2026/12/15 審査中 詳細を見る(会計ソフト利用契約)
<div class="data-table-wrap" tabindex="0">
  <table class="data-table">
    <thead><tr>
      <th scope="col">契約名</th>                              <!-- 幅指定なし: 余白を吸う -->
      <th scope="col" class="data-table-text">概要</th>       <!-- 自由文: 折り返し + 最小幅 -->
      <th scope="col" class="data-table-num">金額</th>        <!-- 数値: 右寄せ + 等幅数字 -->
      <th scope="col" class="data-table-fit">状態</th>        <!-- 固定書式: 内容幅に締める -->
    </tr></thead>
    <tbody><tr>
      <td>本社ビル賃貸借契約</td>
      <td class="data-table-text">…</td>
      <td class="data-table-num">1,200,000円</td>
      <td class="data-table-fit"><span class="badge badge-soft-success">有効</span></td>
    </tr></tbody>
  </table>
</div>

見出し行 — タイトルと、件数・表全体への操作

data-table-header の 1 段目にタイトル、2 段目(data-table-toolbar)の左に表示件数、右に「検索 → アイコンの操作(3 個まで)→ 主操作」を sm でそろえて並べる。検索は虫眼鏡か Enter で確定してから絞り込み(入力のたびには変えない)、絞り込みのパネルには複数の列や列に無い条件(振込月)をまとめる。適用中の条件は操作の行の下にタグで並べ、× で 1 つずつ、「すべて解除」でまとめて解除できる。1 列の値だけで絞るなら列フィルター、並べ替えは列見出し

振込一覧

振込予約と実績

全 8 件

絞り込む 並べ替える その他の操作

状態
2026/09/30 株式会社みどり商事 1,200,000円 予約 山田
2026/09/30 さくら会計事務所 110,000円 予約 佐藤
2026/09/25 株式会社みどり商事 1,200,000円 完了 山田
2026/09/24 山田工務店 385,000円 完了 佐藤
2026/09/22 ひかり印刷 52,800円 失敗 山田
2026/08/29 山田工務店 420,000円 完了 鈴木
2026/08/25 ひかり印刷 48,400円 完了 佐藤
2026/08/20 株式会社あおば 2,750,000円 完了 鈴木
<div class="data-table-header">
  <div class="data-table-heading">
    <h2 class="data-table-title" id="transfers-title">振込一覧</h2>
    <p class="data-table-subtitle">振込予約と実績</p>
  </div>
  <div class="data-table-toolbar">
    <p class="data-table-count" aria-live="polite">全 8 件</p>
    <div class="data-table-actions" role="group" aria-label="振込一覧の操作">
      <form role="search" aria-label="振込一覧の検索">
        <div class="search-input search-input-sm">
          <input type="search" class="search-input-field" aria-label="検索キーワード">…クリア…
          <button type="submit" class="search-input-submit-icon" aria-label="検索">…</button>
        </div>
      </form>
      <span class="tooltip">
        <button type="button" class="icon-btn icon-btn-sm icon-btn-neutral icon-btn-ghost data-table-filter-trigger"
                aria-labelledby="tip-filter" aria-haspopup="dialog" aria-expanded="false" popovertarget="transfers-filter">…</button>
        <span class="tooltip-content" id="tip-filter" role="tooltip">絞り込む</span>
      </span>
      …(アイコンの操作は 3 個まで。4 個目からは more-horizontal の action-menu)
      <button type="button" class="btn btn-sm btn-primary btn-solid">新規登録</button>
    </div>
  </div>
  <div class="data-table-conditions" hidden>   <!-- 適用中の条件。条件が無いときは hidden -->
    <ul class="tag-list" aria-label="適用中の絞り込み条件">
      <li class="tag">
        <span class="tag-label">キーワード: 山田</span>
        <button type="button" class="tag-remove" aria-label="『キーワード: 山田』の絞り込みを解除">…</button>
      </li>
    </ul>
    <button type="button" class="btn btn-sm btn-neutral btn-ghost">すべて解除</button>
  </div>
</div>
<table class="data-table" aria-labelledby="transfers-title">…</table>
<div class="data-table-filter-panel data-table-filter-panel-end" id="transfers-filter" popover role="dialog" aria-label="振込一覧を絞り込む">
  <div class="data-table-filter-field"><label for="f-month">振込月</label><div class="selector selector-sm">…</div></div>
  …
</div>

列フィルター — 列の値で行を絞り込む

見出しの横の data-table-filter-trigger(icon-btn)から Popover を開き、select で値を選んで「適用」で確定する。「リセット」はその列の絞り込みを解除。複数の列の絞り込みは掛け合わせ(AND)。件数は aria-live="polite" で告知し、0 件でも表は消さずに「条件に合うデータがありません」の行を出す

全 8 件

メンバー一覧
氏名 役割 部署 最終ログイン
山田 太郎 管理者 営業 2026/09/24
佐藤 花子 編集者 開発 2026/09/25
鈴木 一郎 閲覧者 営業 2026/09/20
高橋 美咲 編集者 人事 2026/09/22
田中 健 管理者 開発 2026/09/25
伊藤 さくら 閲覧者 人事 2026/08/30
渡辺 翔 編集者 営業 2026/09/18
中村 結衣 閲覧者 開発 2026/09/12
<th scope="col" class="data-table-fit">
  <span class="data-table-filter">
    <span id="col-role">役割</span>
    <button type="button" class="icon-btn icon-btn-sm icon-btn-neutral icon-btn-ghost data-table-filter-trigger"
            aria-label="役割で絞り込む" aria-haspopup="dialog" aria-expanded="false" popovertarget="filter-role">
      <svg class="icon icon-sm" aria-hidden="true"><use href="./icons.svg#lucide-filter"></use></svg>
    </button>
  </span>
</th>
…
<!-- パネルは表の直後に置く(Tab 順はトリガーの直後になる) -->
<div class="data-table-filter-panel" id="filter-role" popover role="dialog" aria-label="役割で絞り込む">
  <div class="selector selector-sm">
    <select class="select" aria-labelledby="col-role">
      <option value="">すべて</option><option>管理者</option><option>編集者</option>
    </select>
  </div>
  <div class="data-table-filter-actions">
    <button type="button" class="btn btn-sm btn-neutral btn-ghost" data-filter-reset>リセット</button>
    <button type="button" class="btn btn-sm btn-primary btn-solid" data-filter-apply>適用</button>
  </div>
</div>

列フィルターの状態

絞り込み中の列はトリガーに data-filtered を付ける(アイコンが primary になり、右上にドットが付く)。aria-label にも適用中の値を含める。右は開いた状態のパネル(is-static-preview)

列フィルターの状態の例
役割 部署
通常 絞り込み中

並べ替え — 列見出しを押して行を並べ替える

見出しの文字ごと data-table-sort のボタンにし、並べ替え中の th にだけ aria-sort を付ける。1 回で昇順、もう一度で降順。金額・日付・よみがなど表示と並び順が違う列は td に data-sort-value(契約名はよみがなで並ぶ)。結果は aria-live="polite" で告知する

契約一覧(並べ替えできる列: 契約名・金額・更新日)
状態
本社ビル賃貸借契約 1,200,000円 2026/09/01 有効
清掃業務委託契約 85,000円 2026/03/31 期限切れ
会計ソフト利用契約 96,000円 2026/12/15 審査中
複合機リース契約 420,000円 2027/01/10 有効
警備業務委託契約 310,000円 2026/06/30 有効
<th scope="col" class="data-table-fit" aria-sort="ascending">   <!-- 並べ替え中の列にだけ付ける -->
  <button type="button" class="data-table-sort">
    更新日
    <svg class="icon icon-sm data-table-sort-icon" aria-hidden="true"><use href="./icons.svg#lucide-chevron-up"></use></svg>
  </button>
</th>
…
<td class="data-table-num" data-sort-value="1200000">1,200,000円</td>   <!-- 表示と並び順が違う値 -->
…
<p class="sr-only" aria-live="polite"></p>   <!-- 「更新日の昇順で並べ替えました」を告知 -->

並べ替えの状態

並べ替えていない列は chevrons-up-down(fg/low)、昇順は chevron-up、降順は chevron-down(primary/700)。色だけでなく形で状態を示す

並べ替えていない列の見本
並べ替えていない
昇順の列の見本
昇順
降順の列の見本
降順

機能

このコンポーネントの用途

列見出しを上に置き、複数データを行で比較する表。
1 件の詳細を縦に並べるなら data-table ではなく simple-table。
列の値で行を絞り込むときは見出しに列フィルター(data-table-filter)、行を並べ替えるときは見出しをボタン(data-table-sort)にする。
表の上に並べて一覧全体を 1 つの軸で切り替えるなら tab、複数条件を同時に掛け合わせるトグルなら filter-chip。
表のタイトルと、表全体に効く操作(検索・複数条件の絞り込み・書き出し・新規作成)は、表の上の見出し行
(data-table-header)にまとめる(タイトルの下の行に、左に表示件数・右に操作)。1 列の値で絞るなら列フィルター。
並べ替えは列見出しのボタンと、見出し行の並べ替えのパネルの両方から行え、状態は連動する。