モダンCSSで実装する、テーブル(<table>)のさまざまなスタイルのまとめ
Post on:2024年2月8日
モダンCSSでテーブルをゼブラストライプしたり、テーブルの四隅を角丸にしたり(昔はかなり面倒でした)、列や行を分割したり、ホバーでハイライトやアウトラインを表示したりなど、表のデータを読みやすくするテーブル(<table>
)のさまざまなスタイルを紹介します。
A Guide to Styling Tables
by Mads Stoumann
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- テーブルを構成するHTMLの要素
- テーブルをゼブラストライブにするCSS
- テーブルを角丸にするCSS
- テーブルの列を分割するCSS
- テーブルの行を分割するCSS
- ホバー・フォーカスでハイライトするCSS
- ホバーでアウトラインを表示するCSS
- データを左右・中央に揃えるCSS
- 終わりに
はじめに
私は最近、小さな矛盾に気がつきました。
かなり昔のことですが、CSS Gridが登場する前はグリッドレイアウトを実装するために<table>
を使用していました。つまり、テーブルでグリッドをシミュレートしていたことになります。しかし、それは間違っています。テーブルは表形式のデータのためにあるのであって、<div>
で表形式のデータを見せることは意味がありません。
この間違った行為の理由は、テーブルのスタイル設定が少し難しいこと、そしてほとんどのCSSフレームワークがデフォルトのテーブルのスタイルにborder-collapse: collapse;
を使用しているからです。この記事で解説しますが、collapse
されたボーダーは、テーブルのスタイルにとって必ずしも有用ではありません。
この記事では、テーブルのさまざまなスタイルについて解説したいと思います。まずは、<table>
の要素をどのように構成し、どのようにスタイルを設定するか解説します。
テーブルを構成するHTMLの要素
テーブルを構成するHTMLの基本的な要素は、<table>
の他に次の3つのタグが必要です。
タグ | 説明 |
---|---|
td |
テーブルのデータのセル |
th |
テーブルのヘッダのセル |
tr |
テーブルの行 |
たとえば、下記のようなHTMLになります。
1 2 3 4 |
<table> <tr><th>ヘッダ</th></tr> <tr><td>コンテンツ</td></tr> </table> |
テーブルをより適切に構造化するために、行を次のようにカプセル化することもできます。
タグ | 説明 |
---|---|
thead |
テーブルのヘッダ |
tbody |
テーブルのボディ |
tfoot |
テーブルのフッタ |
さらに、テーブルに<caption>
を追加し、<colgroup>
内の<col>
で列を定義することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<table> <caption>ヒーロー</caption> <colgroup><col><col><col><col></colgroup> <thead> <tr><th>ファーストネーム</th><th>ラストネーム</th><th>ヒーロー</th><th>場所</th></tr> </thead> <tbody> <tr><td>ブルース</td><td>ウェイン</td><td>バットマン</td><td>ゴッサム・シティ</td></tr> <tr><td>クラーク</td><td>ケント</td><td>スーパーマン</td><td>メトロポリス</td></tr> <tr><td>トニー</td><td>スターク</td><td>アイアンマン</td><td>マリブ</td></tr> <tr><td>ピーター</td><td>パーカー</td><td>スパイダーマン</td><td>ニューヨーク</td></tr> <tr><td>マット</td><td>マードック</td><td>デアデビル</td><td>ニューヨーク</td></tr> </tbody> </table> |
スタイルを設定しない場合、ブラウザは次のように表示します。
See the Pen
A Guide To Styling Tables 0 by coliss (@coliss)
on CodePen.
デフォルトのUAスタイルは次のとおりです。
1 2 3 4 5 |
table { border-collapse: separate; text-indent: initial; border-spacing: 2px; } |
ここで、非常にシンプルなスタイルを追加すると、次のようになります。
1 2 3 |
:is(td,th) { border-style: solid; } |
ブラウザは次のように表示します。
See the Pen
A Guide To Styling Tables 0 by coliss (@coliss)
on CodePen.
テーブルのボーダーが分かれていることに注目してください。見た目はあまり良くないですね。
そこで、折り畳まれたボーダー(collapse
)の人気が高いことを理解するために(およびフォントも)、スタイルを追加します。
1 2 3 4 |
table { border-collapse: collapse; font-family: system-ui; } |
ブラウザは次のように表示します。
See the Pen
A Guide To Styling Tables 1 by coliss (@coliss)
on CodePen.
テーブル内のデータを読みやすくしてみます。
:is(td, th){}
セレクタにpadding: .5ch 1ch;
を追加し、<caption>
にmargin-block: 1rlh;
を追加すると、ブラウザは次のように表示します。
See the Pen
A Guide To Styling Tables 2 by coliss (@coliss)
on CodePen.
ここまでのCSSをまとめると、次の通りです。
1 2 3 4 5 6 7 8 9 |
table { border-collapse: collapse; font-family: system-ui; & caption { margin-block: 1rlh; } &:is(td, th) { border-style: solid; padding: .5ch 1ch; } } |
代わりに<caption>
をテーブルの下に配置するには、次を使用します。
1 2 3 |
table { caption-side: bottom; } |
テーブルをゼブラストライブにするCSS
テーブルの列をゼブラストライプにするには、<col>
にスタイルを設定するだけです。
1 |
col:nth-of-type(even) { background: #F2F2F2; } |
See the Pen
A Guide To Styling Tables 3 by coliss (@coliss)
on CodePen.
行の場合は、<tr>
です。
1 |
tr:nth-of-type(odd) { background: #F2F2F2; } |
See the Pen
A Guide To Styling Tables 4 by coliss (@coliss)
on CodePen.
テーブルを角丸にするCSS
テーブルを角丸にするのは、すこし面倒です。
<table>
にborder-radius
を単に追加するだけでは実現できないため、最初と最後の行の最初と最後のセルをターゲットにします。
1 2 3 4 5 6 7 8 9 10 11 12 |
th { &:first-of-type { border-start-start-radius: .5em } &:last-of-type { border-start-end-radius: .5em } } tr { &:last-of-type { & td { &:first-of-type { border-end-start-radius: .5em } &:last-of-type { border-end-end-radius: .5em } } } } |
しかし、これでは何も起こりません!
その理由は、ボーダーがcollapse
の場合、border-radius
が追加できないからです。
そのため、ボーダーを分割して使用し、collapse
のボーダーを模倣する必要があります。
1 2 3 4 5 6 7 8 |
table { border-spacing: 0; } :is(td, th) { border-block-width: 1px 0; border-inline-width: 1px 0; &:last-of-type { border-inline-end-width: 1px } } |
このCSSで、角丸テーブルを実装できます。
See the Pen
A Guide To Styling Tables 5 by coliss (@coliss)
on CodePen.
テーブルの列を分割するCSS
独立した列を維持し、border-spacing
プロパティでカラム間にスペースを追加します。
1 2 3 4 5 6 |
table { border-spacing: 2ch 0; & :is(td, th) { border-inline-width: 1px; } } |
See the Pen
A Guide To Styling Tables 5 by coliss (@coliss)
on CodePen.
これは単なる<table>
ですが、比較表として使用するとさらに読みやすくなります。
テーブルの行を分割するCSS
行を独立されるためには、border-spacing
プロパティの2番目(y軸)をアップデートするだけです。
1 2 3 4 5 6 |
table { border-spacing: 0 2ch; & :is(td, th) { border-block-width: 1px; } } |
See the Pen
A Guide To Styling Tables 7 by coliss (@coliss)
on CodePen.
ホバー・フォーカスでハイライトするCSS
テーブルが大きいと、どこを見ているか把握することが難しいかもしれません。そこで役立つのが、:hover
です。また、キーボードでナビゲート可能なテーブルを使用している場合は、:focus-visble
が必要になります。
次のテーブルでは、ホバー時のスタイルは<col>
, <tr>
と<td>
の両方に設定されています。
See the Pen
A Guide To Styling Tables 4 by coliss (@coliss)
on CodePen.
行と列のホバー時にハイライトさせるのは簡単です。
1 2 3 4 5 6 7 |
td:hover { background: #666666; } tr:hover { background: #E6E6E6; } |
<col>
のホバーは少し複雑です。
1 2 3 |
col:hover { background: #E6E6E6; } |
上記のCSSでは、機能しません。
しかし、デベロッパーツールでcol
要素を選択し、:hover
を有効にすると機能します。
上記のCSSの代わりに、:has
を使用してセルのホバーをキャプチャし、<col>
要素にスタイルを設定します。
1 2 3 4 |
table { &:has(:is(td,th):nth-child(1):hover col:nth-child(1) { background: #E6E6E6; } |
このCSSを分析してみましょう。
テーブルの<td>
または<th>
がnth-child(1)
であり、現在ホバーされている場合、同じnth-child
を持つ<col>
を選択し、background
を設定します。
そして、このCSSを各列に対して繰り返す必要があります(nth-child(2)
, nth-child(3)
など)。
ホバーでアウトラインを表示するCSS
ホバー時にアウトラインを表示するのも簡単で、セルと行も同じです。ただしオフセットから幅を引く必要があります。
1 2 3 4 |
:is(td, th, tr):hover { outline: 2px solid #666; outline-offset: -2px; } |
See the Pen
A Guide To Styling Tables 9 by coliss (@coliss)
on CodePen.
列のアウトラインを作成するのは非常に難しいですが、見栄えは良くなります。
セルのborder-width
が1px
の場合、<col>
のホバー時にborder-width
を2px
に設定できますが、そうするとテーブル全体がずれてしまいます。
そのため、<col>
に背景グラデーションでボーダーをシミュレートする方法があります。テーブルのセルが透明であれば、これはうまく機能します。
border-radius
で動作させ、セルの背景を維持するために私はセルごとに疑似要素を使用しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
:is(td,th) { position: relative; &::after { border-inline: 2px solid transparent; border-radius: inherit; content: ''; inset: -2px 0 0 0; position: absolute; } } tr:first-of-type th::after { border-block-start: 2px solid transparent; } tr:last-of-type td::after { border-block-end: 2px solid transparent; } |
そして、col-hoverで行ったことと同様に、ホバー時に同じcol-indexを持つすべてのセルをターゲットにします。
1 2 3 |
:has(:is(td,th):nth-child(1):hover :is(td,th):nth-child(1) { border-color: #666; } |
これをすべての列に対して設定します。
データを左右・中央に揃えるCSS
古い仕様では、<col>
要素にalign
プロパティを追加できましたが、これはもう機能しません。
たとえば、2列目のテキストを中央揃えにして、4列目のテキストを右揃えにしてみましょう。
See the Pen
A Guide To Styling Tables 10 by coliss (@coliss)
on CodePen.
各セルにクラスを追加する代わりに、テーブル全体に列ごとにデータ属性を追加します。
1 |
<table data-c2="center" data-c4="end"> |
そして、CSSで中央揃えと右揃えを設定します。
1 2 3 4 5 6 |
[data-c2~="center"] tr > *:nth-of-type(2) { text-align: center; } [data-c4~="end"] tr > *:nth-of-type(4) { text-align: end; } |
あとは、すべての列に対してこれを繰り返します。
終わりに
これでテーブルに関するスタイルのガイドは終わりにしたいと思います。
colspan
, rowspan
, scope
, span
については説明していませんが、詳しく知りたい場合はMDNを読むことをお勧めします。
最後に、この記事で解説したテーブルすべてのデモをご覧ください。
See the Pen
A Guide To Styling Tables by coliss (@coliss)
on CodePen.
sponsors