HTML+CSS table作成の基礎をしっかり理解しよう

サービスの料金表や商品スペックの比較表など使用頻度の高いtable要素。ホームページを制作する上で基本的な要素ですが、設定値もたくさんありすべてを把握できていない人も多いかと思います。今回は、table要素について基礎からしっかりと説明を行っていきます。
目次
table要素の例
下記はゆうパックの運賃表で、table要素を利用して作成しています。文章ではなく表を利用することでパッと見ただけでお届け先の場所、サイズによる運賃の比較を行うことができます。

ゆうパック運賃表
初めてのtableの作成
テーブルの基礎
まず、ゆうパックの運賃表よりも少しシンプルな下記の表の作成方法を確認します。

作成したい表
テーブルを作成するための基本のタグは、table, tr, th, tdの4つです。この4つのタグを概念的に図にしてみると下記のようになります。tableタグの中にtrタグ、trタグの中にthタグやtdタグが入り、tableタグを親要素とした階層構造になっています。

テーブルとタグの関係(概念図)
各タグについて説明を行います。
- tableタグ
table全体を表すタグです。 - trタグ
trタグはtable row(行)の略で、各行を表すタグです。 - thタグ
thタグはtable header(ヘッダー)の略で、列の見出しを表すタグです。 - tdタグ
tdタグはtable data(データ)の略で、データが格納されているセルを表すタグです。テキストデータだけではなく、画像データも格納することができます。
行と列の関係は下記の通りです。頻繁に出てくる用語なので、逆に覚えないように注意しましょう。また行はrow、列はcolumnという英単語が対応するので、覚えているとこれから出てくるタグを覚えるのも楽になります。

テーブルの行と列
HTMLを使用してtableを記述すると下記のようになります。
<table>
<tr>
<th>サイズ</th><th>運賃</th>
</tr>
<tr>
<td>60サイズ</td><td>800円</td>
</tr>
<tr>
<td>80サイズ</td><td>1,010円</td>
</tr>
<tr>
<td>100サイズ</td><td>1,260円</td>
</tr>
</table>
HTMLで記載したテーブルをブラウザで確認するとテーブルには罫線がありません。table属性、もしくはCSSを使用しなければ、罫線は表示されません。

罫線がないテーブル
table属性とCSSを利用した罫線の表示
tableに罫線を設定するためには、属性またはCSSを利用する必要があります。ここでは属性を利用するためtableタグにborder=”1″を設定します。
<table border="1">
<tr>
<th>サイズ</th><th>運賃</th>
</tr>
<tr>
border属性を設定すると罫線が表示されましたが、罫線は2重線で表示されます。

tableタグに属性borderを設定
1重線にするためにCSSのborder-collapseプロパティを利用します。
border-collapseプロパティの初期値はseparateで隣り合うセルのborderを別々に表示させます。collapseに設定すると隣り合うセルのborderを重ね合わせて1重線として表示させます。
table{
border-collapse: collapse;
}
border-collapseをcollapseに設定すると2重線が1重線に変わります。

1重線にするためのborder-collapse設定
ここまでを理解できれば、簡単な表は自分の力で作成することができます。
table要素へのCSSの設定
tableを構成する要素へのmargin,padding設定
テーブルを作成することができましたが、セルの中にあるテキスト文字とborder間に空白がないので少し窮屈な見た目になっています。borderとテキスト文字の間に空間を作るためpaddingを設定します。
th, td{
padding:0.5em;
}
paddingをth, tdに設定するとborderとテキスト間に空間ができることを確認することができます。

td, thにpadding設定
th, tdではpaddingの設定を適用することができますが、marginは適用することができません。
table, tr, th, tdそれぞれの要素によって、padding, marginが適用できるかがどうか異なります。一覧表をまとめると以下のようになります。

table要素へのpadding,margin適用
tableの各要素へのborder設定
table要素へのborder設定をより深く理解するために各要素へ個別にborder設定を行い、どのような表示になるか確認していきましょう。
tableのみにborderの設定を行います。
table{
border:1px solid #000;
}
tableのみにborderを設定すると外側に1重線が表示されます。

tableのみにborder設定
trのみにborderの設定を行います。
tr{
border:1px solid #000;
}
trにborderを設定してもborderは表示されません。

trのみにborder設定
trのみにborderを設定するためには、table要素のborder-collapseプロパティをcollapseに設定する必要があります。collapseに設定するとtrのみにborderが表示されます。

tableのborder-collapseプロパティをcollapseに
th, tdのみborderの設定を行います。
th,td{
border:1px solid #000;
}
セル毎にborderが表示されます。

thとtdのみborder設定
table, th, tdにborderの設定を行います。trについては、border-collapseプロパティをcollpaseに設定しなければ表示されないので、設定を行いません。
table,th,td{
border:1px solid #000;
}
table,tr, tdにborderの設定を行った結果、tableの属性borderに1を設定した時と同じ表示になりました。この結果、borderが2重になる原因は、tableのborderとth, tdの各セルのborderが別々に表示されていることだと理解できたかと思います。

table, th, tdにborder設定
border-collapseの理解
borderの2重線を1重線にするためには、border-collapseプロパティをcollapseにする必要がありました。border-collapseの値をcollapseすると隣接するセルのボーダーを重ねて表示するという動作になるため、2重線が1重線になります。実際にtd, thのみにborderを設定し、tableのborder-collapseの値をcollapseにして確認してみましょう。
table{
border-collapse: collapse;
}
th,td{
border:1px solid #000;
}
先にborder-collapaseが未設定の場合を確認しておきましょう。各セルに表示されたborderは重ならず別々に表示されています。

thとtdのみborder設定
border-collapseの値をcollapseに変更すると隣接セルで分かれていたborderが1本のなることがわかります。

border-collapseを設定、th, tdのみborder
これらの結果から1重線のborderを表示させたい場合は、tableのborder-collapseプロパティをcollapseに設定し、td, thにborderを設定すればいいことがわかります。tableやtrにborderを設定する必要はありません。
セルの結合
横方向の結合
本文書の最初に出てきたゆうパックの運賃表のヘッダーの部分は、2つのセルの結合を行い、1つのセルとして表示をしています。ここでは、セルの横方向での結合の方法を説明していきます。

セルが横方向に結合したテーブル
横方向のセルの結合を行う場合は、thまたはtd要素にcolspan属性を設定します。値には、結合したいセルの数を設定します。


colspanでセルを横方向に結合
th要素の2つのセルでcolspanを設定する場合は、データを表示させたいth要素にcolspanを設定し、残りのth要素は削除します。
<table>
<tr>
<th colspan="2">東京</th>
</tr>
<tr>
<td>60サイズ</td><td>800円</td>
</tr>
<tr>
<td>80サイズ</td><td>1,010円</td>
</tr>
<tr>
<td>100サイズ</td><td>1,260円</td>
</tr>
</table>
ブラウザで確認すると下記のようにセルの横結合を確認することができます。

thにcolspan=”2″を設定し、セルを結合

縦方向の結合
セルの結合は横方向だけではなく縦方向でも行うことができます。下記はある商品のサービスに関する表ですが、赤い四角の部分が縦結合を行っています。

機能表の一部が縦結合
縦方向のセルの結合を行う場合は、thまたはtd要素にrowspan属性を設定します。値には、結合したいセルの数を設定します。


rowspanでセルを縦方向に結合
セルの縦結合を行いたいセルにrowspanを設定します。縦結合を行った行は2つのtdが存在しますが、残りの2つの行については、縦結合を行っているため、1つのtdのみ残しそのセルにデータを入力します。縦結合は横方向のセルの結合よりもわかりにくいので、どこの行のセルを残すのかしっかりと理解しておいてください。
<table>
<tr>
<td rowspan="3">アクセス解析</td><td>アクセス解析ツール</td>
</tr>
<tr>
<td>アクセスログの取得</td>
</tr>
<tr>
<td>エラーログの取得</td>
</tr>
</table>
横結合と縦結合が混在した表
横結合と縦結合が混在した表を作成する場合は、どこのセルにrowspan、colspanを設定し、どのセルを残すのか最初は混乱するかもしれません。下記の表を参考に複雑な表をHTMLで記述してみましょう

colspan, rowspanの設定された表
複雑な表でも上の行から順番に見ていけば思ったりもシンプルな構造なので、上から順にHTMLを記述していきます。施設名は、3つのセルが縦方向に結合されているので、rowspan=”3″を設定します。区分は、結合がないのでそのまま。時間区分は4つのセルが横方向の結合なので、colspan=”4″を設定します。2行目は施設名は無視(rowspanが設定されているため)して、使用日は、2つのセルの縦結合なので、rowspan=”2″を設定し、残りは結合がないので、そのまま記述します。このように上から順番に記述していきます。
<table>
<tr>
<td rowspan="3">施設名</td><td>区分</td><td colspan="4">時間区分</td>
</tr>
<tr>
<td rowspan="2">使用日</td><td>午前</td><td>午後</td><td>夜間</td><td>全日</td>
</tr>
<tr>
<td>9:00~12:00</td><td>13:00~17:00</td><td>18:00~22:00</td><td>9:00~22:00</td>
</tr>
<tr>
<td rowspan="2">大ホール</td><td>平日</td><td>38,470円</td><td>67,890円</td><td>87,120円</td><td>193,480円</td>
</tr>
<tr>
<td>土・日・休日</td><td>52,050円</td><td>91,650円</td><td>118,800円</td><td>262,500円</td>
</tr>
</table>
ブラウザで表示すると下記の表が表示されます。

colspan, rowspanの入った表

行要素(row)のグループ化
thead, tbody, tfootについて
行要素rowはグループ化を行うことができます。行要素rowのグループ化を行うためにthead、tbody、tfootタグを使用します。これらのタグを使うことでCSSをより柔軟に適用することができます。
- thead
theadはtable headerの略で、表のヘッダー部分をグループ化するために使用します。 - tbody
tbodyはtable bodyの略で、表の本体部分をグループ化するために使用します。 - tfoot
tfootはtable footerの略で、表のフッター部分をグループ化するために使用します。
thead, tbodyによるグループ化
先ほど使用した表をヘッダーとボディーの部分で下記のようにグループ化することができます。

theadとtbodyでグループ化
theadとtbodyタグで行(row)をグループ化するとHTMLは下記のようになります。追加したthead, tbodyへのCSSの設定がなければ、ブラウザでの表示への影響はありません。
<table>
<thead>
<tr>
<td rowspan="3">施設名</td><td>区分</td><td colspan="4">時間区分</td>
</tr>
<tr>
<td rowspan="2">使用日</td><td>午前</td><td>午後</td><td>夜間</td><td>全日</td>
</tr>
<tr>
<td>9:00~12:00</td><td>13:00~17:00</td><td>18:00~22:00</td><td>9:00~22:00</td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">大ホール</td><td>平日</td><td>38,470円</td><td>67,890円</td><td>87,120円</td><td>193,480円</td>
</tr>
<tr>
<td>土・日・休日</td><td>52,050円</td><td>91,650円</td><td>118,800円</td><td>262,500円</td>
</tr>
</tbody>
</table>
thead要素の背景色の設定
tableをtheadとtbodyで別々にグループ化させたため、グループ毎に背景色を設定することができます。
table thead{
background-color: #eae4d6;
}
theadタグでグループ化した部分のみCSSの設定で背景色がついています。

theadの背景色を設定
行をグループ化したことでtheadの中のth要素のみCSSを適用するといったことが簡単に行えます。
縦要素(column)のグループ化
thead, tbodyで横要素(row)のグループ化を行いましたが、縦要素のグループ化にはcolgroupを使用します。さらにグループ分けをしたい場合はcolを使用します。

colgroup, colを使用して行の幅を設定する
colgroup,colを使用していない時はテーブルの各セルの幅は自動で設定されます。

列の幅が狭い
すべての列の幅を同じ幅にするためにcolgroupとcolの設定を行います。
<table>
<caption>2018/12/9の料金表</caption>
<colgroup>
<col style="width:16%">
<col style="width:16%">
<col style="width:16%">
<col style="width:16%">
<col style="width:16%">
<col style="width:16%">
</colgroup>
<thead>
<tr>
<td rowspan="3">施設名</td><td>区分</td><td colspan="4">時間区分</td>
</tr>
colタグにstyle属性を付与して、widthプロパティを設定すると同じ幅になります。

colタグにstyleのwidthを設定
colを使用して背景色を設定する
先頭の2列のcolのみ背景色の設定を行います。
<colgroup>
<col style="width=16%;background-color:#f5f2ed">
<col style="width=16%;background-color:#f5f2ed">
<col style="width=16%">
<col style="width=16%">
<col style="width=16%">
<col style="width=16%">
</colgroup>
colには背景色を設定すると色が変わりましたが、施設名、区分、使用日の部分の色は変わりません。colよりもtheadに設定した背景色が優先されるためです。

colに背景色を設定

tableにcaption(説明)をつける
作成したテーブルがどのようなことを記述しているのかキャプション(説明)をつけたい場合は、captionタグを利用します。
<table>
<caption>2018/12/9の料金表</caption>
<thead>
<tr>
<td rowspan="3">施設名</td><td>区分</td><td colspan="4">時間区分</td>
</tr>
captionタグを設定すると表の上部に表示されます。captionをつけると何の表か一目でわかります。

テーブルにcaptionを設定する
まとめ
ここまで理解できればtable要素の大半は網羅できていると思います。table要素は頻繁に使う要素の一つなので、ぜひ今回の知識を利用してわかりやすいテーブルの作成を行ってください。