table 要素

4.9.1 table 要素

カテゴリー:
フロー・コンテント
パルパブル・コンテント
この要素を使うことができるコンテキスト:
フロー・コンテントが期待される場所
コンテントモデル:
この順番で: オプションで 1 つの caption 要素、続いて、0 個以上の colgroup 要素、続いて、オプションで 1 つの thead 要素、続いて、オプションで 1 つの tfoot 要素、続いて、0 個以上の tbody 要素、または、1 個以上の tr 要素、続いて、オプションで 1 つの tfoot 要素(しかし、tfoot 要素は合計で 1 つしか入れられません。)、オプションで、任意の場所に 1 個以上のスクリプトサポート要素
コンテント属性:
グローバル属性
border
sortable - テーブル表にソートのインタフェースを有効にする
text/html におけるタグの省略:
どちらのタグも省略できません。
指定可能な ARIA role 属性 の値:
あらゆるロールの値
指定可能な ARIA ステートとプロパティ属性:
グローバル aria-* 属性
許可ロールに該当する aria-* 属性
DOM インタフェース:
interface HTMLTableElement : HTMLElement {
           attribute HTMLTableCaptionElement? caption;
  HTMLElement createCaption();
  void deleteCaption();
           attribute HTMLTableSectionElement? tHead;
  HTMLElement createTHead();
  void deleteTHead();
           attribute HTMLTableSectionElement? tFoot;
  HTMLElement createTFoot();
  void deleteTFoot();
  readonly attribute HTMLCollection tBodies;
  HTMLElement createTBody();
  readonly attribute HTMLCollection rows;
  HTMLElement insertRow(optional long index = -1);
  void deleteRow(long index);
           attribute DOMString border;
};

table 要素は、テーブルの形式で、1 つ以上の次元をもったデータを表します。

table 要素は、テーブルモデルに属します。テーブルは行、カラム、そして、それらの子孫によって与えられるセルを持ちます。行とカラムはグリッドを形成します。テーブルのセルは、重複せずにグリッドを完全に覆わなければいけません。

この準拠要件を満たしているかどうかを判定する正確な規則は、テーブルモデルで説明されています。

ウェブ制作者は、複雑なテーブルの解釈の方法を説明する情報を提供することが推奨されます。そのような情報を提供する方法に関するガイドラインは後述します。

テーブルをレイアウト目的で使うべきではありません。歴史的に、多くのウェブ制作者が、ページレイアウトを制御する方法として、HTML にテーブルを入れていました。これは、ドキュメントからテーブル形式データを抽出することを困難にしてしまいます。特に、スクリーンリーダーといったアクセシビリティツールのユーザーは、レイアウト目的で使われたテーブルがあると、ページを渡り歩くことがが非常に困難になります。もし、テーブルをレイアウト目的で使うのであれば、role="presentation" という属性を使わなければいけません。これによって、ユーザーエージェントは、支援テクノロジーに対して適切にテーブルを表すことができるようになります。また、ドキュメントからテーブル形式データを抽出しようとするツールに、ウェブ制作者の意図を適切に伝えることができるようになります。

レイアウトに HTML のテーブルを使う代わりの方法はいくつもあります。基本的には、CSS の位置指定や CSS テーブルモデルを使ってください。 [CSS]

border 属性は table 要素に指定することができますが、これは、レイアウト目的で使われていないことを明示的に表すことができます。指定するなら、その属性値は、空文字列か値 "1" のいずれかでなければいけません。この属性は、そのテーブルのセルの周囲にボーダーを引くという指示として、特定のユーザーエージェントによって使われます。


テーブルは複雑になると、理解しにくかったり、ナビゲートしにくかったりすることがあります。これに関してユーザーを助けるべく、ユーザーエージェントは、そのテーブルがレイアウトテーブルとして分類されなかったなら、そのテーブルのセルをお互いに区別できるようはっきりと枠線を描画するべきです。

ウェブ制作者と実装者は、ユーザーが表を渡り歩きやすくするために、後述のテーブルデザインテクニックのいくつかを使うことを考慮することが推奨されます。

ユーザーエージェントは、とりわけ、任意のコンテンツでテーブル解析を行うものは、どのテーブルが実際にデータを含んでいるのか、そして、どのテーブルが単にレイアウト目的に使われているのか、を判定できるような、経験則的な方法を見つけることが推奨されます。本仕様は、正確な経験則的な方法については定義しませんが、次に考え得る目安を提示します:

特徴 目安
値に presentation がセットされた role 属性が使われている レイアウトテーブルの可能性が大きい
非準拠 の値 0 がセットされた border 属性が使われている レイアウトテーブルの可能性が大きい
値 0 がセットされた非準拠の cellspacingcellpadding 属性が使われている レイアウトテーブルの可能性が大きい
caption, thead, th 要素のいずれかが使われている 非レイアウトテーブルの可能性が大きい
headersscope 属性のいずれも使われている 非レイアウトテーブルの可能性が大きい
0 より大きい値がセットされた border 属性が使われているT 非レイアウトテーブルの可能性が大きい
CSS を使って明示的な可視ボーダーがセットされている 非レイアウトテーブルの可能性が大きい
summary 属性が使われている 有効な目安がありません。(レイアウトテーブルにも非レイアウトテーブルにも、歴史的に、この属性が使われてきました。)

上記の目安が間違っている可能性は大いにあります。実装者には、レイアウトテーブル検知の経験則を作ってみて、その経験に関して詳細に説明したフォードバックの提供を強くお願いしたい。


table . caption [ = value ]

該当のテーブルの caption 要素を返します。

値をセットして、caption 要素を置き換えることができます。新しい値が caption 要素でなければ、HierarchyRequestError 例外を投げます。

caption = table . createCaption()

該当のテーブルが確実に caption 要素を持つ状態にしてから、それを返します。

table . deleteCaption()

該当のテーブルが確実に caption 要素を持たない状態にします。

table . tHead [ = value ]

該当のテーブルの thead 要素を返します。

値をセットして、thead 要素を置き換えることができます。新しい値が thead 要素でなければ、HierarchyRequestError 例外を投げます。

thead = table . createTHead()

該当のテーブルが確実に thead 要素を持つ状態にしてから、それを返します。

table . deleteTHead()

該当のテーブルが確実に thead 要素を持たない状態にします。

table . tFoot [ = value ]

該当のテーブルの tfoot 要素を返します。

値をセットして、tfoot 要素を置き換えることができます。新しい値が tfoot 要素でなければ、HierarchyRequestError 例外を投げます。

tfoot = table . createTFoot()

該当のテーブルが確実に tfoot 要素を持つ状態にしてから、それを返します。

table . deleteTFoot()

該当のテーブルが確実に tfoot 要素を持たない状態にします。

table . tBodies

該当のテーブルの tbody 要素の HTMLCollection を返します。

tbody = table . createTBody()

tbody 要素を生成し、それを該当のテーブルに挿入してから、それを返します。

table . rows

該当のテーブルの tr 要素の HTMLCollection を返します。

tr = table . insertRow( [ index ] )

tr 要素を生成します。必要に応じて tbody も生成します。そして、それらを引数に指定された位置に該当のテーブルに挿入してから、生成した tr を返します。

位置は、該当のテーブルの行に対して相対的になります。インデックス -1 は、引数の指定がなかった場合のデフォルトですが、該当のテーブルの最後に挿入することになります。

指定位置が -1 より小さい、または、行の数より大きいなら、IndexSizeError 例外を投げます。

table . deleteRow(index)

該当のテーブルの指定位置にある tr 要素を削除します。

位置は、該当のテーブルの行に対して相対的になります。インデックス -1 なら、該当のテーブルの最後の行を削除することになります。

指定位置が -1 より小さい、または、最後の行のインデックスより大きい、または、行がないなら、IndexSizeError 例外を投げます。

caption IDL 属性は、取得時においては、table 要素の子となる caption 要素があれば、その最初のものを返し、なければ、null を返さなければいけません。セット時においては、もし、新しい値が caption 要素なら、table 要素の子に caption 要素があれば、その最初のものを削除し、それから、table 要素の最初のノードとして、それを挿入しなければいけません。もし、新しい値が caption 要素でなければ、HierarchyRequestError DOM 例外が投げられなければいけません。

createCaption() メソッドは、table 要素の子に caption 要素があれば、その最初のものを返さなければいけません。なければ、新規に caption 要素を生成し、table 要素の最初のノードとしてそれを挿入してから、返さなければいけません。

deleteCaption() メソッドは、table 要素の子に caption 要素があれば、その最初のものを削除しなければいけません。

tHead IDL 属性は、取得時においては、table 要素の子に thead 要素があれば、その最初のものを返し、なければ、null を返さなければいけません。セット時においては、もし、新しい値が thead 要素であれば、table 要素の子に thead 要素があれば、その最初のものを削除しなければいけません。そして、caption 要素でも colgroup 要素でもない要素が table 要素の中にあれば、その最初の要素の直前に、なければ、テーブルの最後に、その新しい値を挿入しなければいけません。新しい値が thead 要素でなければ、HierarchyRequestError DOM 例外が投げなければいけません。

createTHead() メソッドは、table 要素の子に thead 要素があれば、その最初のものを返さなければいけません。なければ、新規に thead 要素を生成し、caption 要素でも colgroup 要素でもない要素が table 要素の中にあれば、その最初の要素の直前に、なければ、テーブルの最後に、新しい値を挿入しなければいけません。それから、その新しい値を返さなければいけません。

deleteTHead() メソッドは、table 要素の子に thead 要素があれば、その最初のものを削除しなければいけません。

tFoot IDL 属性は、取得時においては、table 要素の子に tfoot 要素があれば、その最初のものを返さなければいけません。なければ null を返さなければいけません。セット時においては、もし、新しい値が tfoot 要素であれば、table 要素の子に tfoot 要素があれば、その最初のものを削除しなければいけません。そして、caption 要素でも colgroup 要素でも thead でもない要素が table 要素の中にあれば、その最初の要素の直前に、なければ、テーブルの最後に、その新しい値を挿入しなければいけません。新しい値が tfoot 要素でなければ、HierarchyRequestError DOM 例外が投げなければいけません。

createTFoot() メソッドは、table 要素の子に tfoot 要素があれば、その最初のものを返さなければいけません。なければ、新規に tfoot 要素を生成し、caption 要素でも colgroup 要素でも thead でもない要素が table 要素の中にあれば、その最初の要素の直前に、なければ、テーブルの最後に、その新しい値を挿入しなければいけません。それから、その新しい値を返さなければいけません。

deleteTFoot() メソッドは、table 要素の子に tfoot 要素があれば、その最初のものを削除しなければいけません。

tBodies 属性は、table ノードをルートとした HTMLCollection を返さなければいけません。ただし、table 要素の子である tbody 要素に一致するもののみにフィルターされます。

createTBody() メソッドは、tbody 要素を新規に生成しなければいけません。そして、table 要素に tbody 要素があれば、その最後のものの直後に、table 要素の子に tbody 要素がなければ、table 要素の最後に、それを挿入しなければいけません。それから、その新たな tbody 要素を返さなければいけません。

rows 属性は、table ノードをルートとした HTMLCollection を返さなければいけません。ただし、table 要素の子である、または、table 要素の子の thead, tbody, tfoot のいずれかの子である tr 要素に一致するもののみにフィルターされます。このコレクションの要素は、まず thead が親となるものからツリー順に並び、続いて、table または tbody 要素が親となる要素がツリー順に並び、最後に、tfoot 要素が親となる要素がツリー順に並ぶようにしなければいけません。

insertRow(index) メソッドの挙動は、テーブルの状態に依存します。呼び出された時には、このメソッドは、テーブルの状態と index 引数を説明している次の条件のリストのうち、最初の項目の要求の通りに動作しなければいけません:

index が -1 より小さい、または、rows コレクションの要素数より大きい場合:
このメソッドは、IndexSizeError 例外を投げなければいけません。
rows コレクションに要素がなく、かつ、table 要素に tbody 要素がない場合:
このメソッドは、tbody 要素を生成してから、tr 要素を生成し、それから、tbody 要素に、その tr 要素を追加し、それから、その tbody 要素を table 要素に追加してから、最後に、その tr 要素を返さなければいけません。
rows コレクションに要素がない場合:
このメソッドは、tr 要素を生成してから、該当のテーブルにある最後の tbody 要素にそれを追加し、そして、その tr 要素を返さなければいけません。
index が -1、または、rows コレクションの項目の数に等しい場合:
このメソッドは、tr 要素を生成し、rows コレクションの最後の tr 要素の親にそれを追加し、それから、その新たに生成した tr 要素を返さなければいけません。
上記に該当しない場合:
このメソッドは、tr 要素を生成し、rows コレクションの中で、同じ親を持つ index 番目の tr 要素の直前に、それを挿入し、最後に、その新たに生成した tr 要素を返さなければいけません。

deleteRow(index) メソッドが呼び出されたときには、ユーザーエージェントは、次の手順を実行しなければいけません:

  1. index が -1 に等しいなら、index は、rows コレクションの項目数から 1 を引いた数字にセットされなければいけません。

  2. この時点で、index が 0 より小さい、または、rows コレクションの要素の数より大きい、または、等しいなら、このメソッドは、IndexSizeError 例外を発出し、これらの手順を中止しなければいけません。

  3. そうででなければ、このメソッドは、rows コレクションの index 番目の要素を、その親から削除しなければいけません。

border IDL 属性は、同じ名前のコンテント属性を反映しなければいけません。

これは、数独パズルをマークアップするために使われてるテーブルの例です。ヘッダーが欠落している点に注目してください。こういったテーブルには必要ありません。

<section>
 <style>
  table { border-collapse: collapse; border: solid thick; }
  colgroup, tbody { border: solid medium; }
  td { border: solid thin; height: 1.4em; width: 1.4em; text-align: center; padding: 0; }
 </style>
 <h1>今日の数独</h1>
 <table>
  <colgroup><col><col><col>
  <colgroup><col><col><col>
  <colgroup><col><col><col>
  <tbody>
   <tr> <td> 1 <td>   <td> 3 <td> 6 <td>   <td> 4 <td> 7 <td>   <td> 9
   <tr> <td>   <td> 2 <td>   <td>   <td> 9 <td>   <td>   <td> 1 <td>
   <tr> <td> 7 <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td> 6
  <tbody>
   <tr> <td> 2 <td>   <td> 4 <td>   <td> 3 <td>   <td> 9 <td>   <td> 8
   <tr> <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td>   <td>
   <tr> <td> 5 <td>   <td>   <td> 9 <td>   <td> 7 <td>   <td>   <td> 1
  <tbody>
   <tr> <td> 6 <td>   <td>   <td>   <td> 5 <td>   <td>   <td>   <td> 2
   <tr> <td>   <td>   <td>   <td>   <td> 7 <td>   <td>   <td>   <td>
   <tr> <td> 9 <td>   <td>   <td> 8 <td>   <td> 2 <td>   <td>   <td> 5
 </table>
</section>
4.9.1.1 テーブルを説明するテクニック

見出しとなるセルのグリッドが最初の行や最初のカラムだけで成り立たないテーブルや、一般的に読者がコンテンツを理解するのが難しいテーブルに対しては、ウェブ制作者は、そのテーブルを紹介する説明情報を入れるべきです。この情報は、すべてのユーザーにとって有益なだけでなく、とりわけ、スクリーンリーダーのユーザーのように、そのテーブルを見ることができないユーザーにとっては、有益なものになります。

こういった説明情報は、そのテーブルの目的を紹介し、基本的なセルの構造をまとめ、傾向やパターンをはっきりさせ、一般的に、そのテーブルをどうやって使うのかをユーザーに教えるものとするべきです。

例えば、次のテーブルなら:

プラス面とマイナス面を持ち合わせた特徴
マイナス面 特徴 プラス面
悲しい 気分 幸せ
不合格 成績 合格

... そのテーブルがレイアウトされた理由を説明する文章があれば分かりやすくなるでしょう。例えば、次のような文章です。"2 番目のカラムに特徴が入れられています。その左側のカラムにはマイナス面が、右側にはプラス面が入れられています"。

この情報を入れる方法はいくつかあります:

テーブルの前後の本文の中
<p id="summary">次のテーブルでは、2 番目のカラムに特徴が
入れられています。その左側のカラムにはマイナス面が、右側にはプラス面が
入れられています。</p>
<table aria-describedby="summary">
 <caption>プラス面とマイナス面を持つ特徴</caption>
 <thead>
  <tr>
   <th id="n"> マイナス面
   <th> 特徴
   <th> プラス面 
 <tbody>
  <tr>
   <td headers="n r1"> 悲しい
   <th id="r1"> 気分
   <td> 幸せ
  <tr>
   <td headers="n r2"> 不合格
   <th id="r2"> 成績
   <td> 合格
</table>

この上記の例では、支援技術のユーザーのために、 aria-describedby 属性を使って、テーブルの情報を明示的に関連付けています。

テーブルの caption の中
<table>
 <caption>
  <strong>プラス面とマイナス面を持つ特徴。</strong>
  <p>2 番目のカラムに特徴が入れられています。その左側の
  カラムにはマイナス面が、右側にはプラス面が入れられて
  います。</p>
 </caption>
 <thead>
  <tr>
   <th id="n"> マイナス面
   <th> 特徴
   <th> プラス面
 <tbody>
  <tr>
   <td headers="n r1"> 悲しい
   <th id="r1"> 気分
   <td> 幸せ
  <tr>
   <td headers="n r2"> 不合格
   <th id="r2"> 成績
   <td> 合格
</table>
同じ figure の中でテーブルのとなり
<figure>
 <figcaption>プラス面とマイナス面を持つ特徴</figcaption>
 <p>2 番目のカラムに特徴が入れられています。その左側の
 カラムにはマイナス面が、右側にはプラス面が入れられて
 います。</p>
 <table>
  <thead>
   <tr>
    <th id="n"> マイナス面
    <th> 特徴
    <th> プラス面
  <tbody>
   <tr>
    <td headers="n r1"> 悲しい
    <th id="r1"> 気分
    <td> 幸せ
   <tr>
    <td headers="n r2"> 不合格
    <th id="r2"> 成績
    <td> 合格
 </table>
</figure>
figure の中でテーブルのとなりの figcaption の中
<figure>
 <figcaption>
  <strong>プラス面とマイナス面を持つ特徴</strong>
  <p>2 番目のカラムに特徴が入れられています。その左側の
  カラムにはマイナス面が、右側にはプラス面が入れられて
  います。</p>
 </figcaption>
 <table>
  <thead>
   <tr>
    <th id="n"> マイナス面
    <th> 特徴
    <th> プラス面
  <tbody>
   <tr>
    <td headers="n r1"> 悲しい
    <th id="r1"> 気分
    <td> 幸せ
   <tr>
    <td headers="n r2"> 不合格
    <th id="r2"> 成績
    <td> 合格
 </table>
</figure>

ウェブ制作者は、必要に応じて、他のテクニックや、前述のテクニックの組み合わせも使うことができます。

もちろん、最善の選択肢は、テーブルのレイアウト方法を解説した説明文を書くのではなく、説明が必要とならないようなテーブルに調整することです。

前述の例で使われたテーブルの場合、簡単に再構成するとしたら、ヘッダーをトップと左におきます。こうすることで、説明の必要がなくなり、headers 属性を使う必要もなくなります:

<table>
 <caption>プラス面とマイナス面を持つ特徴</caption>
 <thead>
  <tr>
   <th> 特徴
   <th> マイナス面
   <th> プラス面
 <tbody>
  <tr>
   <th> 気分
   <td> 悲しい
   <td> 幸せ
  <tr>
   <th> 成績
   <td> 不合格
   <td> 合格
</table>
4.9.1.2 テーブルのデザインのテクニック

良いテーブルレイアウトの要諦は、より読みやすく使いやすくすることです。

ビジュアルメディアでは、カラムと行にボーダーを与え、行の背景を交互に変えれば、複雑なテーブルをより読みやすくする上では、非常に効果的です。

膨大な数値のコンテンツを伴うテーブルに対しては、等幅フォントを使うと、ユーザーはパターンが見やすくなるでしょう。ユーザーエージェントがボーダーをレンダリングしない状況においては、なおさらです。(残念なことに、歴史的な理由で、一般にデフォルトは、テーブルにボーダーをレンダリングしません。)

スピーチメディアにおいては、セルのコンテンツが読まれる前に、対応するヘッダーが読み上げられることで、そして、ソース順にテーブルのすべてのコンテンツをつなげられるのではなく、ユーザーがテーブルをグリッド単位で渡り歩けるようにすることで、そのテーブルのセルは区別することができるようになります。

ウェブ制作者は、これらの効果を実現するために CSS を使うことが推奨されます。

ユーザーエージェントは、ページに CSS が使われていないときや、レイアウトテーブルとして分類されないときは、これらのテクニックを使ってテーブルをレンダリングすることが推奨されます。


※ 原文:http://www.w3.org/TR/2014/REC-html5-20141028/tabular-data.html#the-table-element