HTMLのtableの使い方と、CSSによるtableデザインの基本をわかりやすく解説します。
tableの基礎をしっかり理解することで、いろいろな形式の表(テーブル)が作れるようになります。
tableで表を作ってみよう
tableを使うときは、視覚的な表をイメージしてからHTMLを割り当てると理解しやすいです。
まず、表の完成形をイメージします。具体的には、見出しの有無や、行と列の数などです。

次に、イメージした表の骨組みをHTMLに置き換えていきます。
表全体をtableタグで囲います。tableの中に、必要な行の数だけtrタグを配置します。
そして、trの中に、セルにあたるthタグとtdタグを配置して、その中に表示する内容を記述します。thは見出し、tdはデータ(内容)を意味するHTMLです。
行を増やす場合は、trのブロックをまるごと追加します。列を増やす場合は、trブロック内のthとtdを追加します。
慣れないうちはコードが多くて複雑に見えますが、このように考えるとシンプルなコードの塊だということがわかります。
HTMLコードの書き方と手順
HTMLコードの書き方の例として、シンプルな表を作ってみましょう。
まず、表の一番外側を<table></table>
で囲います。これが1つの表のベースになります。
tableタグの直下には、表のブロックを意味する<tbody></tbody>
を配置しておきます。実は、tbodyタグは、なくてもブラウザ上では、あるものとして認識されますが、HTML5では推奨していますので、積極的に使いましょう。
<table>
<tbody>
</tbody>
</table>
次に、tbodyの中に行のブロックを意味する<tr></tr>
を行の数だけ配置します。今回は、3行を想定して、3ブロック記述します。
<table>
<tbody>
<tr></tr>
<tr></tr>
<tr></tr>
</tbody>
</table>
最後に、1行目の見出しをthで、2行目以降の内容をtdで、3列を想定して、trの中にセルを3つずつ配置します。
<table>
<tbody>
<tr>
<th>商品名</th>
<th>料金</th>
<th>備考</th>
</tr>
<tr>
<td>商品A</td>
<td>8,000円</td>
<td>送料無料</td>
</tr>
<tr>
<td>商品B</td>
<td>5,000円</td>
<td>数量限定</td>
</tr>
</tbody>
</table>
これで、見出しを含めて、3行3列の表ができました。
商品名 | 料金 | 備考 |
---|---|---|
商品A | 8,000円 | 送料無料 |
商品B | 5,000円 | 数量限定 |
ちなみに、セルの部分は、見出しとなるth要素がない場合、td要素のみで構成することもできますので覚えておきましょう。
また、thの配置を変えることで、1列目を見出しにすることもできます。
<table>
<tbody>
<tr>
<th>商品A</th>
<td>8,000円</td>
<td>送料無料</td>
</tr>
<tr>
<th>商品B</th>
<td>5,000円</td>
<td>数量限定</td>
</tr>
<tr>
<th>商品C</th>
<td>2,000円</td>
<td>数量限定</td>
</tr>
</tbody>
</table>
こちらが、1列目の商品名を見出しとして構成した表になります。
商品A | 8,000円 | 送料無料 |
---|---|---|
商品B | 5,000円 | 数量限定 |
商品C | 2,000円 | 数量限定 |
tableで使えるHTMLタグ
上記のほかにも、table要素の中で使えるHTMLタグがありますので、よく使われるタグをまとめておきます。
HTML | 意味 | 数量ルール | 配置できる場所 |
---|---|---|---|
caption | 表のタイトルや説明 | 0~1 | tableの最初 |
thead | 表のヘッダー | 0~1 | tableの最初 |
tfoot | 表のフッター | 0~1 | tableの最後 |
tbody | 表のブロック | 0以上 | tableの最初、theadの後、tfootの前 |
tr | 行のブロック | 1以上必須 | table、tbody、thead、tfootの直下 |
th | 見出しのセル | 0以上 | trの直下 |
td | データ(内容)のセル | 1以上必須 | trの直下 |
「数量ルール」は、1つのtableタグの中で使えるタグの数です。例えば、captionタグは、<table></table>
の中で、無くてもいいし、配置する場合は1つまでというルールになります。つまり、数量ルールが0のタグは、表の構成上、必要なければ使わなくてもOKということになります。反対に、trとtdは、必ず1つ以上は必要です。
これらのHTMLをすべて使って表を構成すると、このようなコードになります。
<table>
<caption>
表のタイトル
<p>表の説明文</p>
</caption>
<thead>
<tr>
<th>見出し</th>
<th>見出し</th>
<th>見出し</th>
</tr>
</thead>
<tbody>
<tr>
<td>データ内容</td>
<td>データ内容</td>
<td>データ内容</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>合計内容</td>
<td>合計内容</td>
<td>合計内容</td>
</tr>
</tfoot>
</table>
ブラウザで見るとこのような表になります。
見出し | 見出し | 見出し |
---|---|---|
データ内容 | データ内容 | データ内容 |
合計内容 | 合計内容 | 合計内容 |
これらのHTMLタグは、表の意味や構造にあわせて使いわけてください。
シンプルな表であれば、table、thead、tbody、tr、th、tdを使った構成が一般的です。
表をCSSで装飾デザインしてみよう
HTMLの表の作り方を理解したところで、CSSでデザインをしていきます。
CSSの基本的なテクニックを知っておくことで、さまざまな表のデザインを作れるようになります。
例として、以下のHTMLで作成した表をベースに解説します。
<table>
<thead>
<tr>
<th>商品名</th>
<th>料金</th>
</tr>
</thead>
<tbody>
<tr>
<td>商品A</td>
<td>8,000円</td>
</tr>
<tr>
<td>商品B</td>
<td>5,000円</td>
</tr>
</tbody>
</table>
表のセル間の隙間の調整
表の枠線の隙間の調整は、border-collapseを使います。
border-collapseは線の間に隙間を作るかどうかを決めるCSSのプロパティです。
値に、separateを指定することで隙間を作ることができます。隙間のサイズは、border-spacingプロパティに、サイズとなる値を指定します。
table {
border-collapse: separate;
border-spacing: 5px;
}
例では、5pxの隙間を装飾しています。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表のセル間の隙間を削除
ブラウザによっては、上記で解説したborder-collapseのデフォルト値が、separateになっている場合があります。その場合、デフォルト値の隙間を削除しておくことで、枠線をスタイリングしやすくなります。
セル間の隙間を削除し、一重線に変えるには、border-collapseプロパティの値に、collapseを指定します。
table {
border-collapse: collapse;
}
セルとセルの間の隙間がなくなって、表の線だけになっています。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表の罫線
表に罫線を装飾してみましょう。tableとセルにあたるth、tdに対して、それぞれ異なる線を指定してみます。線は、borderプロパティを使います。
table {
border-collapse: collapse;
border: 2px solid black;
}
table th,
table td {
border: 1px dashed gray;
}
表の外枠には、太めの2pxの黒い線が、thとtdのセルには、1pxのグレーの点線を装飾できました。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表のセル内の余白
例として、thは上下5pxと左右20px、tdは上下左右20pxのpadding値を設定してみましょう。
table {
border-collapse: collapse;
}
/* 上下5px・左右10pxの余白*/
table th {
padding: 5px 20px;
}
/* 上下左右15pxの余白*/
table td {
padding: 20px;
}
それぞれのセル内に余白を設定することができました。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表の文字フォントと色
フォントサイズはfont-sizeやfont-weightプロパティ、文字の色はcolorプロパティで、thとtdに設定することができます。
例では、table要素にまとめてフォントサイズ12pxを指定して、thとtdに異なる文字の太さと色で指定してみましょう。
/* table全体に適用するフォントサイズ */
table {
border-collapse: collapse;
font-size: 12px;
}
/* thのフォントの太さと色*/
table th {
font-weight: bold;
color: blue;
}
/* tdのフォントの色 */
table td {
font-weight: 400;
color; gray;
}
これで、セル内の文字のフォントサイズと色を指定することができました。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表のセルの背景色
背景色は、backgroundプロパティで設定します。表全体の背景色は、tableに指定しますが、thとtdにもそれぞれ背景色を設定することができます。
例では、わかりやすいように、table全体の背景に薄いブルーを、thの背景に濃いネイビーを指定して文字の色を白にしてみましょう。
/* table全体に適用する背景色 */
table {
border-collapse: collapse;
background: #eaf6fe;
}
/* thの背景色*/
table th {
color: #fff;
background: #14116e;
}
これで、thの見出しの部分とその他のセルの背景色を変えることができました。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
表の奇数行の背景色
表の奇数行だけ背景色を付けるときは、疑似クラスを使います。
疑似クラスについては、こちらで詳しく解説していますので参考にしてください。
例では、見出しであるthを除く、tdの奇数行に限定して背景色を設定してみます。この場合は、行のブロックに対して疑似クラスを指定します。
table th {
color: #fff;
background: #14116e;
}
/* 奇数行のtd要素 */
table tr:nth-child(odd) td {
background: #eaf6fe;
}
tr:nth-child(odd) td
と書くことで、tr要素内にある奇数のtd要素を対象にすることができます。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
商品C | 2,000円 |
見出しを除くtdの奇数行である1行目と3行目の背景色を変えることができました。
例えば、thとtdが1つの行のブロック<tr></tr>
の中に存在しているケースではどうでしょうか。
<table>
<tbody>
<tr>
<th>商品A</th>
<td>8,000円</td>
<td>備考</td>
</tr>
<tr>
<th>商品B</th>
<td>5,000円</td>
<td>備考</td>
</tr>
<tr>
<th>商品C</th>
<td>2,000円</td>
<td>備考</td>
</tr>
</tbody>
</table>
このケースでは、奇数行にあたるthにも同じように疑似クラスを指定することで、背景色を設定します。
tableに対して、tr:nth-child(odd) th
とtr:nth-child(odd) td
の両方を設定することで、tr要素内にある奇数のth要素とtd要素を対象にすることができます。
/* 奇数行のthとtd要素 */
table tr:nth-child(odd) th,
table tr:nth-child(odd) td {
background: #eaf6fe;
}
thとtdが混在する行全体に対して交互に背景色を付けることができました。
商品A | 8,000円 | 備考 |
---|---|---|
商品B | 5,000円 | 備考 |
商品C | 2,000円 | 備考 |
表の偶数行の背景色
次は、表の偶数行だけ背景色を付ける場合も見ておきましょう。考え方は奇数行と同じく、疑似クラスを使います。
例では、見出しであるthを除く、tdの偶数行に限定して背景色を設定します。
table th {
color: #fff;
background: #14116e;
}
/* 偶数行のtd要素 */
table tr:nth-child(even) td {
background: #eaf6fe;
}
tr:nth-child(even) td
と書くことで、tr要素内にある偶数のtd要素を対象にすることができます。
商品名 | 料金 |
---|---|
商品A | 8,000円 |
商品B | 5,000円 |
商品C | 2,000円 |
見出しを除くtdの偶数行である2行目の背景色を変えることができました。
表の奇数列に背景色
次は、表の列の背景色を指定してみましょう。まずは、奇数列です。
考え方は、行のときと同じように、疑似クラスを使います。
例では、見出しであるthを除く、tdの奇数列に背景色を設定します。
table th {
color: #fff;
background: #14116e;
}
/* td要素の奇数列 */
table tr td:nth-child(odd) {
background: #eaf6fe;
}
tr td:nth-child(odd)
と書くことで、tr要素内にあるtdの奇数の要素を対象にすることができます。tdに対して疑似クラスを指定している点に注意してください。
商品名 | 価格 | カラー | サイズ |
---|---|---|---|
商品A | 6,000円 | ブラック | S・M・L・XL |
商品B | 3,000円 | ホワイト | S・M・L |
tdの奇数列にあたる1列目と3列目に背景色を付けることができました。
表の偶数列の背景色
偶数列の背景色を指定してみましょう。奇数列と同じように、td要素に対して疑似クラスを指定します。
table th {
color: #fff;
background: #14116e;
}
/* td要素の偶数列 */
table tr td:nth-child(even) {
background: #eaf6fe;
}
tr td:nth-child(even)
と書くことで、tr要素内にあるtdの偶数の要素を対象にすることができます。
商品名 | 価格 | カラー | サイズ |
---|---|---|---|
商品A | 6,000円 | ブラック | S・M・L・XL |
商品B | 3,000円 | ホワイト | S・M・L |
tdの偶数列にあたる2列目と4列目に背景色を付けることができました。
表のセルの左右・中央寄せ
tableのセル内の要素の左右配置の位置は、左寄せがデフォルト値です。
例として、見出しのth要素を中央揃え、td要素を右寄せにしてみましょう。
/* thの文字を中央に配置*/
table th {
color: #fff;
background: #14116e;
text-align: center;
}
/* tdの文字を右寄に配置*/
table td {
text-align: right;
}
それぞれの要素に、text-alignプロパティを指定することで中央・左右に配置することができます。
メニュー | メイン | 料金 |
---|---|---|
ランチA | 魚 | 800円 |
ランチB | 肉 | 1,000円 |
次は、tdの最後の列の要素だけを右寄せに配置してみましょう。
/* th要素を中央に配置*/
table th {
color: #fff;
background: #14116e;
text-align: center;
}
/* td要素の最後の列を右寄に配置*/
table tr td:last-child {
text-align: right;
}
tr td:last-child
と書くことで、tr要素内にあるtdの最後の要素を対象にすることができます。
メニュー | メイン | 料金 |
---|---|---|
ランチA | 魚 | 800円 |
ランチB | 肉 | 1,000円 |
最後の要素を意味する疑似クラスを指定することで、表の料金の部分だけを右寄せにすることができました。
次は、tdの2番目以降の列だけを右寄せに配置してみましょう。
/* th要素を中央に配置*/
table th {
color: #fff;
background: #14116e;
text-align: center;
}
/* td要素の2番目以降の列を右寄に配置*/
table tr td:nth-child(n+2) {
text-align: right;
}
tr td:nth-child(n+2)
と書くことで、tr要素内にあるtdの2番目以降の要素を対象にすることができます。
メニュー | メイン | 料金 |
---|---|---|
ランチA | 魚 | 800円 |
ランチB | 肉 | 1,000円 |
表のメインと料金の部分を右寄せにすることができました。
表のセルの上下・中央寄せ
tableのセル内の要素の縦方向の上下配置は、vertical-alignプロパティで設定します。
vertical-alignの値は、topが上端揃え、middleが中央揃え、bottomが下端揃えでしたね。
例として、セル内に複数行の要素がある場合を想定して、td要素の中央揃えの配置を確認してみましょう。
/* 縦方向の中央揃え */
table td {
vertical-align: middle;
}
表の1列目と3列を見ると、上下中央に配置されているのがわかります。
ランチA | トマトポタージュ サラダ 真鯛のポワレ魚 ライスまたはパン |
800円 |
ランチB | トマトポタージュ サラダ 牛肉の赤ワイン煮 ライスまたはパン |
1,000円 |
続いて、td要素の上揃えの配置を確認してみましょう。vertical-alignの値にtopを指定します。
/* 縦方向の上揃え */
table td {
vertical-align: top;
}
表の1列目と3列を見ると、上端に配置されましたね。
ランチA | トマトポタージュ サラダ 真鯛のポワレ魚 ライスまたはパン |
800円 |
ランチB | トマトポタージュ サラダ 牛肉の赤ワイン煮 ライスまたはパン |
1,000円 |
最後に、td要素の下揃えの配置を確認してみます。vertical-alignの値にbottomを指定します。
/* 縦方向の下揃え */
table td {
vertical-align: bottom;
}
表の1列目と3列を見ると、下端に配置されました。
ランチA | トマトポタージュ サラダ 真鯛のポワレ魚 ライスまたはパン |
800円 |
ランチB | トマトポタージュ サラダ 牛肉の赤ワイン煮 ライスまたはパン |
1,000円 |
表全体の幅
表全体の幅は、tableにwidthプロパティで調整できます。
例として、幅いっぱいの100%と、200pxで見てみましょう。
/* 幅100% */
table {
width: 100%;
text-align: center;
}
/* 幅200px */
table {
width: 200px;
text-align: center;
}
幅100%のほうは、親要素の幅いっぱいのサイズになっています。ブラウザの幅にあわせて伸び縮みするので、レスポンシブの対応をする場合は、このようにパーセント値で指定することが多いです。
エリア | 最高 | 最低 | 降水 |
---|---|---|---|
札幌 | 2 | -3 | 50% |
東京 | 14 | 5 | 20% |
大阪 | 10 | 5 | 10% |
福岡 | 11 | 2 | 30% |
一方、幅200pxのほうは、固定値で表示されていますね。
エリア | 最高 | 最低 | 降水 |
---|---|---|---|
札幌 | 2 | -3 | 50% |
東京 | 14 | 5 | 20% |
大阪 | 10 | 5 | 10% |
福岡 | 11 | 2 | 30% |
表のセルの幅
まずは、表のセルの幅を調整するための基本的なプロパティを紹介します。
セルの幅調整の基本として、表全体のセルの幅を均等にするか、または、文字量に応じて自動調整するかを設定することができます。そのプロパティが、table-layoutです。それぞれの値は、fixedまたはautoで指定します。
まずは、セルを均等幅にしてみましょう。table-layout: fixed;
を設定します。
table {
width:100%;
text-align: center;
table-layout: fixed; /* セルの均等幅 */
}
結果は、表のセルの幅がすべて均等になっていますね。
主要エリア | 最高 | 最低 | 降水量 |
---|---|---|---|
札幌 | 2 | -3 | 50% |
東京 | 14 | 5 | 20% |
大阪 | 10 | 5 | 10% |
福岡 | 11 | 2 | 30% |
次に、セルを文字数に応じて自動調整されるように、table-layout: auto;
を設定して比較してみます。
table {
width:100%;
text-align: center;
table-layout: auto; /* セルの自動幅 */
}
文字数の多いセルが少し幅広になっているのがわかります。
主要エリア | 最高 | 最低 | 降水量 |
---|---|---|---|
札幌 | 2 | -3 | 50% |
東京 | 14 | 5 | 20% |
大阪 | 10 | 5 | 10% |
福岡 | 11 | 2 | 30% |
デフォルトでは、fixedを指定しない場合は、文字量に応じて自動調整されるようになっているので、特定のセルのみを幅調整するときは、table-layoutプロパティは設定しないことが多いです。
次は、特定のセルを指定して幅を調整してみましょう。
これまで見てきた疑似クラスを使って、特定のセルを指定することができます。
例として、表の1列目を100px、2列目と3列目を50pxにしてみましょう。
table {
width:100%;
text-align: center;
table-layout: auto; /* デフォルト値のため無しでもOK */
}
/* td要素の1列目 */
table tr td:first-child {
width: 100px;
}
/* td要素の2列目と3列目 */
table tr td:nth-child(2),
table tr td:nth-child(3) {
width: 50px;
}
結果は、表の1列目が100px、2列目3列目が50pxの固定幅になりました。4列目は、tableに設定した100%から1~3列目の合計値200pxを差し引いた幅になっています。
主要エリア | 最高 | 最低 | 降水量 |
---|---|---|---|
札幌 | 2 | -3 | 50% |
東京 | 14 | 5 | 20% |
大阪 | 10 | 5 | 10% |
福岡 | 11 | 2 | 30% |
このように、tableのセルの幅は、レスポンシブ対応も考えて、基本はパーセント値、一部をピクセルなどの固定値で調整することも多いので覚えておきましょう。
テキストの折り返し制限
表のセルの中でテキストを改行なしで1行におさめたいときが多々あります。その場合は、white-spaceプロパティを使うことで折り返しを制限することができます。
white-spaceの初期値は、normalでセルの幅にあわせてテキストが折り返しされますが、折り返しを制限する場合は、nowrapを指定します。
まずは、比較するためにwhite-spaceを指定しない場合の表を見てみましょう。
書籍タイトル | 説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。 |
書籍タイトル | 説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。 |
初期値のnormalが適用されるのでセルの幅にあわせてテキストは折り返します。
次に、nowrapを指定して、表の1列目のテキストを改行なしの1行でおさめてみましょう。
table {
width:100%;
}
/* td要素の1列目 */
table tr td:first-child {
white-space: nowrap;
}
書籍タイトル | 説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。 |
書籍タイトル | 説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。説明が入ります。 |
normalとnowrapの違いがわかりますね。このように、white-spaceは、表の中でテキストを1行におさめたいときに使える便利なプロパティです。
まとめ
これまで見てきたtableの基本基礎を組み合わせて、いろいろな形状の表を作ることができます。
また、表の装飾デザインについては、行や列、特定のセルに対してCSSを指定するための疑似クラスの知識も欠かせません。疑似クラスを活用することで、より複雑なテーブルデザインを実現することが可能になります。
疑似クラスについては、こちらで詳しく解説していますので、ぜひ参考にしてください。