HTML

A semantic HTML element for presenting real “data tables” in rows and columns with clear headings, so people and screen readers can understand which values belong to which labels, with practical tips for captions, header cells, and mobile-friendly display.

table要素

料金表・比較表・集計結果のように「行」と「列」で揃ったデータを、読み手にもスクリーンリーダーにも迷いにくい形で伝えるための table 要素の使いどころを、基本から実務のコツまでまとめたページです。見た目だけのレイアウト目的で使うのではなく、「対応関係があるデータ」を正しく表すために使う、という感覚がつかめるように構成しています。

table要素の主な役割

行と列で「対応関係のあるデータ」を表現する
table は、数字や項目が「どの見出しに属するか」という対応関係が大事な情報を、構造として表すための要素です。見た目がそれっぽいだけではなく、「この値はこの項目のこと」と分かる形を作れます。
見出し(header)を持てるため、読み取りが速くなる
表は行数・列数が増えるほど、読み手は迷います。th(見出しセル)と scope(効く範囲)を使うと、「どこを見れば何が分かるか」がはっきりします。
支援技術(スクリーンリーダー等)でも意味が伝わりやすい
表の構造が正しいと、読み上げ時に見出しと値のセットが理解しやすくなります。逆に、div で表っぽく作ると、見た目は整っても読み上げが崩れやすいです。

table要素と似た表現との違い

「レイアウト目的の表もどき」との違い

リスト(ul / ol / dl)との違い

table要素を使うときの注意点

「見た目をそろえる」目的で使わない
昔はレイアウトに table を使うこともありましたが、今は推奨されません。レイアウトはCSS、データ表は table と役割分担すると、後からの修正も安全です。
見出しは th を使い、必要なら scope を付ける
太字にしたいから th、という使い方ではなく、「ここは見出しセル」という意味で th にします。scope="col"(列見出し)や scope="row"(行見出し)を付けると対応関係がさらに明確になります。
スマホでは横幅が足りないのが普通
表は横に広がりがちです。無理に潰さず、横スクロールの容器で包む、表を分割する、重要列だけ残すなど「逃げ道」を用意しておくと実務で困りにくいです。

Sample

料金プラン一覧(例)
プラン 月額 容量 サポート
ライト 500円 5GB メール
スタンダード 980円 20GB メール / チャット
プロ 1980円 100GB 優先対応

HTML

<div class="tableScroll">
    <table>
        <caption>料金プラン一覧(例)</caption>

        <thead>
            <tr>
                <th scope="col">プラン</th>
                <th scope="col">月額</th>
                <th scope="col">容量</th>
                <th scope="col">サポート</th>
            </tr>
        </thead>

        <tbody>
            <tr>
                <th scope="row">ライト</th>
                <td class="num">500円</td>
                <td>5GB</td>
                <td>メール</td>
            </tr>
        </tbody>
    </table>
</div>

CSS

.tableScroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

table {
    border-collapse: collapse;
    width: 100%;
}

caption {
    text-align: left;
    font-weight: 700;
    margin-bottom: 8px;
}

th,
td {
    border: 1px solid #ddd;
    padding: 8px 10px;
    vertical-align: top;
}

td.num {
    text-align: right;
    white-space: nowrap;
}

このサンプルのポイントは、caption で表の意味を一言で示し、列の見出しは scope="col"、行の見出しは scope="row" にして、どの値がどの見出しに属するかを構造として確定させているところです。スマホでは横幅が足りないことが多いので、外側を overflow-x: auto; の容器で包み、横スクロールできる逃げ道も用意しています。

見出しセル(th)と scope の考え方

表が読みづらくなる原因の多くは、「どの値が、何の値なのか」が追いにくいことです。そこで効くのが th(見出しセル)と scope(見出しの効く範囲)です。

th は「太字セル」ではなく「見出しセル」
見た目の太字は副作用として付いてくるだけで、本体は「見出しである」という意味付けです。デザイン目的ならCSSで太字にできますが、意味付けはCSSではできません。
scope="col"(列の見出し)
上段にある見出しが「この列にある値は何を表すか」を示すときに使います。料金表なら「月額」「容量」などが該当します。
scope="row"(行の見出し)
左側にある見出しが「この行が何のデータか」を示すときに使います。プラン名や人物名などが該当します。
複雑な表は “分割できないか” を先に考える
colspan/rowspan で見出しが複雑になるほど、保守と読み上げ対応が難しくなりがちです。表を2つに分ける、段階表示にするなど、設計で助ける方が安全なことも多いです。

実務メモ:レスポンシブ対応の現実解

表は情報密度が高く、スマホでは横幅が足りないことがよくあります。よく使われる現実解を、使いどころの感覚と一緒にまとめます。

横スクロールを許可する(迷ったらこれ)
表の構造を壊さず、データの対応関係もそのまま保てます。ユーザーに「横にスクロールできる」ことが伝わるよう、周辺に短い案内を添えるとさらに親切です。
列数が多すぎるなら、表を分割する
比較対象を増やしすぎると、PCでも追いにくくなります。重要度が近い単位で表を分ける方が読みやすいことがあります。
スマホ用に別UI(カード等)を用意する
表をCSSで無理に崩すと、読み上げやコピーが不自然になることがあります。情報の意味が複雑な場合は、表示戦略を変える方が結果的にやさしいです。

よくある質問(FAQ)

「表っぽい見た目」にしたいだけでも table を使うべきですか?
基本は使いません。見た目の並びが目的ならCSS(Flex/Grid)で作る方が安全です。table は、行と列で「対応関係があるデータ」を扱うときに使います。
thead / tbody / tfoot は必須ですか?
必須ではありませんが、見出し・本文・合計など役割が分かれているなら入れるのがおすすめです。CSSで整えやすくなり、読み手にも構造が伝わりやすくなります。
caption は付けた方がいいですか?
付けるのがおすすめです。「これは何の表か」が一言で分かると、表が複数あっても迷いにくくなります。見出し(見出し文)を表の外に置くより、まず caption を検討すると筋がいいです。
scope を付けないとダメですか?
小さく単純な表では省略しても伝わることがありますが、迷ったら付けるのがおすすめです。読み上げや複雑化への耐性が上がります。
スマホで横が切れて読めません
表を横スクロールできる容器で包むのが手堅いです。列数が多すぎる場合は表を分割したり、表示方法そのものを見直す判断も有効です。

よくあるエラー・誤用早見表

レイアウトのために table を使ってしまう
表の意味がズレて、読み上げや保守が難しくなります。配置はCSS、データ表は table で役割分担します。
見出しなのに td を使っている
見出しは th にします。必要なら scope="col"/scope="row" で効く範囲も明確にします。
caption がなく、表の意味が一瞬で分からない
表が何を表すかを caption で短く示すと迷子が減ります。表の前後に文章がある場合でも、まずは caption を検討します。
列が多すぎてスマホが破綻している
横スクロール容器で包む、表を分割する、重要列だけ残すなど、表示戦略を用意します。
colspan/rowspan を増やしすぎて保守が難しい
複雑な表は分割や段階表示の方が理解しやすいことがあります。まず分割できないか検討してから使います。