あなたに合った学習プランは?LINE適正コース診断はこちら プログラミングが全て無料で学習可能!
【HTML】tbodyタグは必要?役割や勝手に自動生成される理由を解説 - 忍者CODEマガジン

【HTML】tbodyタグは必要?役割や勝手に自動生成される理由を解説

プログラミング言語の辞書

HTMLで表を作るときに、<tbody>というタグを見かけることがあります。しかし、「tbodyタグは必要なの?」「書かなくても表示されるならいらないのでは?」「コードに書いていないのに検証画面でtbodyが勝手に入っているのはなぜ?」と疑問に感じる方も多いはずです。

tbodyタグは、HTMLテーブルの本体データ行をまとめるためのタグです。省略しても表示される場合がありますが、CSSやJavaScriptで表を扱うときのトラブルを防ぐため、実務では明示的に書くのがおすすめです。

この記事では、「html tbody」と調べている方に向けて、tbodyタグの役割、必要性、ブラウザが自動生成する理由、table > trでCSSが効かない落とし穴、複数tbodyの使い方まで解説します。

HTMLのtbodyタグとは?

tbodyタグは、テーブルの本体部分にあたる行をまとめるHTMLタグです。読み方は「ティーボディ」で、table bodyの略として覚えると分かりやすいです。

<table>
  <thead>
    <tr>
      <th>タグ</th>
      <th>役割</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>tbody</td>
      <td>テーブル本体の行をまとめる</td>
    </tr>
  </tbody>
</table>

この例では、theadに見出し行、tbodyに本体データ行を入れています。tbodyの中には、直接tdを書くのではなく、trタグで行を作り、その中にtdやthを入れます。

tbodyは「表の本体データ」をまとめる

テーブルは、大きく分けると次の3つのグループにできます。

タグ 役割 入れる内容
<thead> 見出し行をまとめる 列名、項目名
<tbody> 本体データ行をまとめる 通常のデータ
<tfoot> 末尾行をまとめる 合計、注釈、集計

tbodyタグは見た目を変えるためのタグではありません。表の本体部分をHTML構造として分けるためのタグです。

tbodyの中に入るのはtrタグ

tbodyの中には、0個以上のtrタグを入れます。tdやthはtrタグの中に入れます。

【NG例】
<tbody>
  <td>HTML</td>
  <td>構造を作る</td>
</tbody>
【OK例】
<tbody>
  <tr>
    <td>HTML</td>
    <td>構造を作る</td>
  </tr>
</tbody>

tbodyは行グループ、trは行、td・thはセルと分けて覚えると整理しやすくなります。

tbodyはいらない?必要性と書くメリット

結論からいうと、tbodyを書かなくても表が表示されるケースはあります。ただし、HTML構造、CSS、JavaScriptの扱いやすさを考えると、tbodyは省略せずに書くのがおすすめです。

tbodyを書かなくても表示されることはある

次のように、table直下にtrを書いても、多くのブラウザでは表として表示されます。

<table>
  <tr>
    <td>HTML</td>
    <td>構造を作る</td>
  </tr>
</table>

表示されるため、「tbodyはいらないのでは?」と思うかもしれません。しかし、ブラウザ内部のDOMではtbodyが補われることがあり、CSSやJavaScriptで意図しないズレが起きる原因になります。表示されることと、管理しやすいHTMLであることは別です。実務ではtbodyを明示的に書く方が安全です。

tbodyを書くと構造が読みやすくなる

tbodyを明示することで、開発者がコードを読みやすくなるだけでなく、音声読み上げブラウザ(スクリーンリーダー)などの支援技術が表のデータ構造を正しく解釈しやすくなるというメリット(アクセシビリティの向上)もあります。

<table>
  <thead>
    <tr>
      <th>項目</th>
      <th>内容</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML</td>
      <td>Webページの構造</td>
    </tr>
  </tbody>
</table>

tbodyは「表の本体データはここからここまで」と示す目印になります。

メリット①:JavaScriptで表のデータだけを狙い撃ちできる

tbodyを書く大きなメリットの1つが、JavaScriptで表の本体データだけを扱いやすくなることです。

tbody内の行だけを取得する

たとえば、見出し行を除いて、データ行だけを取得したい場合があります。

【HTML】
<table id="course-table">
  <thead>
    <tr>
      <th>講座</th>
      <th>料金</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML講座</td>
      <td>無料</td>
    </tr>
    <tr>
      <td>CSS講座</td>
      <td>無料</td>
    </tr>
  </tbody>
</table>
【JavaScript】
const rows = document.querySelectorAll("#course-table tbody tr");

rows.forEach((row) => {
  console.log(row.textContent);
});

このように書くと、theadの見出し行を除外して、tbody内のデータ行だけを取得できます。

tbodyを明示しておくと、JavaScriptで「表の本体だけ」を指定しやすくなります。

実務でよくある使い道

制作現場では、tbodyを使って次のような処理を行うことがあります。

  • 検索結果テーブルのデータ行だけを更新する
  • 一覧表に新しい行を追加する
  • チェックされた行だけを取得する
  • 合計金額を再計算する
const tbody = document.querySelector("#course-table tbody");

const newRow = document.createElement("tr");
newRow.innerHTML = "<td>JavaScript講座</td><td>無料</td>";

tbody.appendChild(newRow);

tbodyがあると、見出し行に影響を与えずにデータ行だけを追加できます。

JavaScriptでtable全体を雑に操作すると、theadやtfootまで巻き込んでしまうことがあります。データ行だけを触りたい場合はtbodyを基準にしましょう。

メリット②:CSSで「ヘッダー以外」に一括でスタイルを当てられる

tbodyを使うと、CSSで表の本体部分だけにスタイルを当てやすくなります。特に、ヘッダー行を除いて背景色や余白を調整したいときに便利です。

tbodyだけに背景色を付ける

【CSS】
.course-table thead {
  background-color: #f0f0f0;
}

.course-table tbody {
  background-color: #fff;
}

このように書くと、見出し部分と本体部分の装飾を分けられます。

データ行だけ一行おきに色を変える

tbodyがあると、見出し行を含めずにデータ行だけをストライプ表示できます。

.course-table tbody tr:nth-child(even) {
  background-color: #f7f7f7;
}

theadを含めずにtbody内だけを数えるため、色の付き方がずれにくくなります。

tbodyを使えば、ヘッダー以外の本体行だけにCSSを当てやすくなります。

tbodyを省略するとCSSの指定が分かりにくくなる

tbodyを書かずにtable直下のtrを狙おうとすると、後述する自動補完の影響でCSSが効かない場合があります。

table > tr {
  background-color: #f7f7f7;
}

この指定は、「tableの直接の子であるtr」を選ぶCSSです。しかしブラウザがtbodyを補うと、trはtableの直接の子ではなく、tbodyの子になります。

CSSで表の行を安定して指定したいなら、tbodyを明示してtbody trのように書く方が安全です。

コードに書いていないのにtbodyが勝手に入る原因

HTMLを書いていると、コードにはtbodyを書いていないのに、ブラウザの検証画面ではtbodyが表示されることがあります。これはバグではありません。ブラウザがHTMLを解釈するときに、テーブル構造を補ってDOMを作っているためです。

ブラウザが親切心で自動補完してしまう仕様

たとえば、次のようにtbodyを書かずにtable直下へtrを書いたとします。

【自分で書いたHTML】
<table>
  <tr>
    <td>HTML</td>
    <td>構造を作る</td>
  </tr>
</table>

ブラウザの検証画面では、次のようにtbodyが入って見えることがあります。

【ブラウザが解釈したDOMのイメージ】
<table>
  <tbody>
    <tr>
      <td>HTML</td>
      <td>構造を作る</td>
    </tr>
  </tbody>
</table>

MDNでも、tr要素をtableの直接の子として書いた場合、ブラウザがそれらを囲むtbody要素を生成することがあると説明されています。

コードにtbodyを書いていなくても、ブラウザのDOM上ではtbodyが補われることがあります。

HTMLソースと検証画面が違って見える理由

「ページのソースを表示」で見えるHTMLは、自分が書いた元のHTMLに近いものです。一方、開発者ツールのElementsで見える内容は、ブラウザが解釈した後のDOMです。そのため、tbodyのようにブラウザが補った要素は、開発者ツールでは見えるのに、元のHTMLファイルには書かれていないことがあります。

検証画面にtbodyがあるからといって、誰かが勝手にファイルを書き換えたわけではありません。ブラウザの解釈後の構造として表示されています。

【重要】table > trでCSSが効かなくなる落とし穴と対策

tbodyが自動生成されることを知らないと、CSSでつまずきやすくなります。代表例が、table > trというセレクタです。

table > trが効かない理由

>は「直接の子要素」を指定するCSSセレクタです。

table > tr {
  background-color: #f7f7f7;
}

このCSSは「tableの直下にあるtr」を指定しています。しかし、ブラウザがtbodyを補うと、実際のDOMは次のようになります。

<table>
  <tbody>
    <tr>
      <td>HTML</td>
    </tr>
  </tbody>
</table>

この場合、trはtableの直接の子ではなく、tbodyの子です。そのため、table > trは当たりません。

tbodyを省略したテーブルでtable > trが効かない場合、ブラウザがtbodyを補っている可能性があります。

対策:tbody trを指定する

表の本体行を指定したい場合は、tbodyを明示し、CSSでもtbody trを指定しましょう。

【HTML】
<table class="course-table">
  <tbody>
    <tr>
      <td>HTML</td>
      <td>構造を作る</td>
    </tr>
  </tbody>
</table>
【CSS】
.course-table tbody tr {
  background-color: #f7f7f7;
}

テーブルの行にCSSを当てるときは、tbodyを省略せずに書き、CSSでもtbody trを指定すると安定します。

実務Tips:開発者ツールでDOMを確認する

CSSが効かないときは、ブラウザの開発者ツールでtableの中身を確認しましょう。自分ではtbodyを書いていなくても、Elements上ではtbodyが追加されていることがあります。

  • HTMLファイル:tbodyを書いていない
  • 開発者ツール:tbodyが表示されている
  • CSS:table > trではなくtbody trを使う

【応用】1つのテーブルの中にtbodyを複数使ってもいいの?

tbodyは、1つのtableの中で複数使うことができます。大きな表でデータのグループが分かれている場合に便利です。

データのグループが複数に分かれる場合の正しい書き方

たとえば、講座一覧を「HTML/CSS」と「JavaScript」で分けたい場合は、tbodyを複数使ってグループ化できます。

【HTML】
<table class="group-table">
  <thead>
    <tr>
      <th scope="col">講座</th>
      <th scope="col">内容</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th colspan="2">HTML/CSS</th>
    </tr>
    <tr>
      <td>HTML入門</td>
      <td>タグの基本を学ぶ</td>
    </tr>
    <tr>
      <td>CSS入門</td>
      <td>見た目の調整を学ぶ</td>
    </tr>
  </tbody>

  <tbody>
    <tr>
      <th colspan="2">JavaScript</th>
    </tr>
    <tr>
      <td>JavaScript入門</td>
      <td>動きを付ける基本を学ぶ</td>
    </tr>
  </tbody>
</table>

このように、tbodyを複数使うことで、表の本体データを意味のあるまとまりに分けられます。

複数tbodyは連続して書く

複数のtbodyを使う場合は、tbody同士を連続して書きます。間にtheadやtfootを挟むような書き方は避けましょう。

<table>
  <thead>...</thead>
  <tbody>...</tbody>
  <tbody>...</tbody>
  <tfoot>...</tfoot>
</table>

MDNでも、1つのtable内で複数のtbodyを使えるが、それらは連続している必要があると説明されています。

データのグループが複数に分かれる表では、tbodyを複数使って構造を分けても問題ありません。

tbodyごとにCSSを変える

tbodyにclassを付ければ、グループごとに色や余白を変えられます。

<tbody class="html-css-group">...</tbody>
<tbody class="js-group">...</tbody>
.html-css-group {
  background-color: #f7fbff;
}

.js-group {
  background-color: #fffdf2;
}

ただし、グループ分けが不要な小さな表でtbodyを細かく分けすぎると、かえって読みづらくなります。

テーブルの構造を理解するために一緒に学ぶべきタグ

tbodyを理解すると、HTMLテーブルの構造がかなり整理しやすくなります。あわせて、trとtheadのに関しても学ぶと、表の「行」「見出し」「本体」の関係がつながります。

  • tr:横1行を作るタグ
  • thead:見出し行をまとめるタグ
  • tbody:本体データ行をまとめるタグ

公式ドキュメントも確認する

tbodyや関連するテーブル要素の仕様を正確に確認したい場合は、公式ドキュメントも参考になります。

まとめ:トラブルを防ぐためにもtbodyは省略せずに書こう!

この記事では、HTMLのtbodyタグについて解説しました。

tbodyタグは、テーブルの本体データ行をまとめるためのタグです。tbodyを書かなくても表が表示されることはありますが、ブラウザが自動的にtbodyを補うことがあります。その結果、table > trのようなCSSが効かない、JavaScriptで狙った行を取得しにくい、といったトラブルにつながる場合があります。

JavaScriptで本体データだけを操作したいとき、CSSでヘッダー以外にスタイルを当てたいとき、大きな表を複数グループに分けたいときは、tbodyを明示しておくと管理しやすくなります。HTMLテーブルをきれいに作るなら、trで行を作り、theadで見出し行をまとめ、tbodyで本体データをまとめる流れを覚えておきましょう。