結論

プロは表を「飾る」のではなく、ノイズを引くことで読みやすくする。文字は左揃え・数値は右揃え+等幅数字(tabular-nums)で桁を縦に揃え、罫線は1pxの極薄グレーかゼブラのどちらか一方だけ、行高は40/48/56pxの3段密度・セル左右16px(列間32px)を守る。Material Designのトークン(行52px/ヘッダ56px、罫線on-surface 12%、hover 4%)を信頼できるベースラインにすれば、ほとんどの表は「装飾を増やさず」読みやすくなる。

01 — 数値は右揃え+tabular-nums、文字は左揃え

最も安っぽく見える原因は数値の中央揃え・左揃えだ。数字は一の位から右→左へ桁を比較するので右揃えが原則。文字は左→右に読み辞書順で比べるので左揃え。中央揃えは行頭・行末がギザギザ(ragged)になり視線が左右に飛ぶため、チェックボックスや星アイコンだけに限定する。ヘッダの揃えも列データに追従させると縦のエッジが揃う。

1,250
98
14,008
307
✗ 中央揃え → 桁がバラけて大小が比較できない
1,250
98
14,008
307
✓ 右揃え → 一の位が揃い、桁数=大小が一目で分かる

blogDesign Better Data Tables — Matthew Ström (Mission Log)

02 — 等幅数字(tabular-nums)で桁を縦に揃える

右揃えにしても、プロポーショナル数字のままだと「1」と「8」で字幅が違い、桁が縦に揃わずガタつく。font-variant-numeric: tabular-nums lining-nums(古い環境用にfont-feature-settings:"tnum" 1,"lnum" 1)で全数字を等幅化すると、列がきれいな縦のグリッドになる。SF Pro/Work Sansは真のtabular figuresを持つ。なければmonospaceがフォールバック。

1,111
8,888
1,818
10,945
✗ プロポーショナル数字 → 右揃えでも桁の縦線がガタつく
1,111
8,888
1,818
10,945
✓ tabular-nums → 各桁が等幅で縦にぴったり揃う

blogDesign Better Data Tables — Matthew Ström (Mission Log)

03 — 罫線かゼブラ、どちらか一方に絞る

縦横フル罫線の格子は、データより罫線が目立ち1990年代のスプレッドシート印象になる。構造は余白と整列で作り、罫線は1px極薄グレー(Material基準 on-surface 12%)の横線のみ・必要箇所だけ。ゼブラを使うなら罫線は外す——交互の塗りが行区切りの役割を果たすので併用は冗長でノイズになる。

商品在庫
USB-Cケーブル120
充電器45
モバイルバッテリー8
✗ 全セルに濃い格子 → 罫線がデータより目立つ
商品在庫
USB-Cケーブル120
充電器45
モバイルバッテリー8
✓ 横罫線のみ・極薄 → 余白と整列で構造を作る

blog9 Design Techniques for User-Friendly Tables — UX Movement

04 — ゼブラは「1色・1行ごと・極薄4%」が最安全解

行の取り違えを防ぐゼブラだが、濃い色で塗ると縞模様自体がノイズになる。正解は on-surface 約4% opacity の極薄グレーで、1行交互の単色。A List Apartの実証(n=2,276)では単色1行ゼブラが8問中3問で素のテーブルより正答率が有意に高く、残りも有意差なし=悪化させない安全策。迷ったら密で長い表のデフォルトにする。

東京1,250
大阪980
名古屋640
福岡410
✗ 濃いゼブラ → 縞そのものがノイズになり読みにくい
東京1,250
大阪980
名古屋640
福岡410
✓ 4% opacityの極薄ストライプ → 行は追えるが邪魔しない

primaryZebra Striping: More Data for the Case — A List Apart

05 — 行を詰めすぎない(40/48/56pxの3段密度)

密度を上げすぎる(30px以下)とパースエラーが増え、かえって読みにくくなる。行高は Condensed 40px / Regular 48px / Relaxed 56px の名前付き3モードを基本に、セル左右パディングは最低16px(列間32px)。Materialの基準は行52px・ヘッダ56px。読み物用途ならRegular 48px固定で十分だ。

注文 #1042¥3,200
注文 #1043¥980
注文 #1044¥12,400
注文 #1045¥540
✗ 26pxに詰めすぎ → 行の取り違え・誤読が増える
注文 #1042¥3,200
注文 #1043¥980
✓ Regular 48px+左右16px → 行に呼吸があり追いやすい

blogData Table Design UX Patterns & Best Practices — Pencil & Paper

06 — ヘッダは sticky で固定する

縦スクロールで列ラベル(=文脈)が消えると、どの列が何の数値か分からなくなる。position:sticky; top:0 でヘッダを固定すれば、スクロール中もラベルが残る。注意点は背景——sticky要素は不透明背景(#fffなど)にしないと下の行が透けて破綻する。下のデモは両方ともスクロールできる。

日付売上
06/141,200
06/15980
06/161,540
06/17760
06/182,010
06/191,330
06/20890
✗ 固定なし → スクロールするとヘッダが消え文脈を失う
日付売上
06/141,200
06/15980
06/161,540
06/17760
06/182,010
06/191,330
06/20890
✓ sticky+不透明背景 → スクロールしてもラベルが残る

blogData Table Design UX Patterns & Best Practices — Pencil & Paper

実装スニペット

読みやすいベーステーブル。罫線は横線のみ・極薄、文字左揃え・数値右揃え+tabular-nums。

table {
  width: 100%;
  border-collapse: collapse;
  font-feature-settings: "palt"; /* 日本語の約物詰め */
}
th, td {
  padding: 14px 16px;            /* 縦14 / 左右16(列間32) */
  text-align: left;              /* 文字は左揃え */
  vertical-align: middle;
  border-bottom: 1px solid rgba(0,0,0,.12); /* Material: on-surface 12% */
  color: rgba(0,0,0,.87);        /* 本文 on-surface 87% */
}
thead th {
  height: 56px;                  /* ヘッダはボディ+4px */
  font-weight: 600;
  color: rgba(0,0,0,.6);
  border-bottom: 2px solid rgba(0,0,0,.12);
}
tbody tr { height: 52px; }       /* Material 基準行高 */

/* 数値列: 右揃え+等幅数字 */
.num, td.num, th.num {
  text-align: right;
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1; /* 古い環境のフォールバック */
}

ゼブラを使うなら横罫線は消す(冗長回避)。塗りは4% opacityまで。

tbody tr:nth-child(even) { background: rgba(0,0,0,.04); } /* on-surface 4% */
tbody tr:nth-child(even) td,
tbody tr:nth-child(odd)  td { border-bottom: none; }

/* hover / 選択も極薄に */
tbody tr:hover { background: rgba(0,0,0,.04); }
tbody tr[aria-selected="true"] { background: rgba(25,118,210,.04); } /* primary 4% */

sticky ヘッダ+左端列固定。固定要素は必ず不透明背景に。

.table-scroll { overflow: auto; max-height: 70vh; }

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #fff;              /* 透けないよう不透明背景必須 */
}
/* 左端の識別子列を横スクロールで固定 */
th:first-child, td:first-child {
  position: sticky;
  left: 0;
  background: #fff;
  z-index: 1;
}
thead th:first-child { z-index: 3; } /* 角は最前面 */

密度3モード+レスポンシブ。data-density属性で切り替える。

:root { --row-h: 48px; --cell-py: 12px; --cell-px: 16px; } /* Regular */
[data-density="condensed"] { --row-h: 40px; --cell-py: 8px;  }
[data-density="relaxed"]   { --row-h: 56px; --cell-py: 22px; }

tbody tr { height: var(--row-h); }
th, td   { padding: var(--cell-py) var(--cell-px); }

/* タッチ操作対象は密度に関係なく48px確保 */
td .action, td input[type="checkbox"] { min-height: 48px; min-width: 48px; }

@media (max-width: 1080px) {
  :root { --cell-py: 8px; --cell-px: 10px; } /* モバイルは詰める */
}

チェックリスト

  • 文字セルは左揃え、数値セルは右揃えになっているか(中央揃えはチェックボックス・星・アイコンのみ)
  • 数値列に font-variant-numeric: tabular-nums lining-nums を指定し、桁が縦に揃っているか
  • ヘッダの揃えを列データに追従させたか(数値列のヘッダは右揃え)
  • 罫線かゼブラのどちらか一方に絞ったか(両方併用していないか)
  • 罫線は1px・極薄グレー(on-surface 12%相当)の横線のみで、縦の格子を引いていないか
  • ゼブラは単色・1行交互・4% opacityの極薄に抑えたか
  • 行高は40/48/56pxのいずれか、セル左右パディングは最低16px(列間32px)あるか
  • 長い表でヘッダを position:sticky 固定し、その背景を不透明にしたか
  • 同一列内で小数桁・桁区切り・通貨表記を統一したか
  • タッチUIなら操作対象(チェックボックス等)が48px以上あるか

限界 / 出典

注意:(1) Materialの52px等は「デフォルト」であり絶対値ではない。密度3段(40/48/56)のRegular相当で、プロジェクトでは48px固定でも妥当。 (2) A List Apartのゼブラ研究は2008年前後の古いデータで、8問中4問は有意差なし=ゼブラは「悪化させない安全策」であって万能ではない。短い/インタラクティブな表ではむしろ外す。 (3) 整列・tabular-numsの主張は主にブログ由来でRCTではないが、専門家間のコンセンサスは非常に強く実務的に信頼できる。 (4) opacityベースのトークンはsticky・重なり要素で透けて破綻するため、固定列・固定ヘッダは必ず不透明背景に解決する。 (5) 16px/32pxパディングはデスクトップ前提。モバイルは8〜10pxまで詰めてよい。 (6) font-variant-numeric はフォントがtabular figuresを持つ場合のみ有効。 (7) 触り対象48pxはタッチUI限定で、ポインタ専用の業務画面では緩めてよい。

primarymaterial-components-web mdc-data-table _data-table-theme.scss

primaryData tables — Material Design (m2)

primaryZebra Striping: More Data for the Case — A List Apart

blogDesign Better Data Tables — Matthew Ström (Mission Log)

blogData Table Design UX Patterns & Best Practices — Pencil & Paper

blogThe Ultimate Guide to Designing Data Tables — UI Prep

blog9 Design Techniques for User-Friendly Tables — UX Movement

blogData table UI design reference guide for 2026 — Setproduct