できない.dev

CSSでテーブルの行を交互に色分けするには

tbody tr:nth-child(even) で偶数行だけに背景色を敷き、行を足しても縞模様が自動で追従するテーブルの基本形を示す。
ホバー中の行を目立たせる指定も併せて扱う。

公開: 更新:

プレビュー
<table class="stripe">
  <thead>
    <tr><th>コマンド</th><th>役割</th></tr>
  </thead>
  <tbody>
    <tr><td>git status</td><td>作業ツリーの状態を見る</td></tr>
    <tr><td>git add</td><td>変更をステージに載せる</td></tr>
    <tr><td>git commit</td><td>ステージの内容を記録する</td></tr>
    <tr><td>git push</td><td>コミットをリモートへ送る</td></tr>
  </tbody>
</table>
.stripe {
  width: 100%;
  border-collapse: collapse;
  font-family: system-ui;
  font-size: 14px;
}
 
.stripe th,
.stripe td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid #e4e4e7;
}
 
.stripe thead th {
  background: #0f766e;
  color: #fff;
}
 
/* 数える範囲を tbody に限定する。見出し行を巻き込むと縞が 1 行ずれる */
.stripe tbody tr:nth-child(even) {
  background: #f4f4f5;
}
 
/* 縞と同じ詳細度なので、後に書いた側がホバー時に勝つ */
.stripe tbody tr:hover {
  background: #ccfbf1;
}

tbody tr:nth-child(even) は「tbody の中の偶数番目の行」を選ぶセレクタで、偶数行だけに背景色を敷けば縞模様になる。

行ごとにクラスを振らないのは、行を 1 本足したり並べ替えたりするたびに HTML 側を直す手間をなくすためである。

つまずき

縞が 1 行ずれて見えるときは、見出し行が数える対象に混ざっていないかを疑う。
:nth-child は同じ親を持つ兄弟の中で順番を数える。

  • thead と tbody を分けて書いていれば、見出し行は tbody の数に入らない
  • thead を書かず、見出し行も本文行も同じ tbody に入っているとずれる

HTML に tbody を書かなくてもブラウザが解析時に自動で補うため、後者では見出し行が tbody の 1 行目として数えられてしまう。

できない例: thead を書かない(縞が 1 行ずれる)
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
th, td {
  padding: 6px 10px;
  text-align: left;
}
th {
  background: #0f766e;
  color: #fff;
}
tbody tr:nth-child(even) {
  background: #e4e4e7;
}
できる例: 見出し行を thead に入れる
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
th, td {
  padding: 6px 10px;
  text-align: left;
}
th {
  background: #0f766e;
  color: #fff;
}
tbody tr:nth-child(even) {
  background: #e4e4e7;
}

背景色が付かないとき

行に背景色を指定したのに変化が見えないときは、セル側にも背景色が付いていないかを確認する。
テーブルの背景は次の順に重ねて描かれ、後のものほど手前に来る。

  • テーブル本体
  • 行グループ
  • 行
  • セル

td に background を指定していると、その下にある行の背景は覆い隠されて見えない。
縞模様を行単位で制御したいなら、セルの背景は透明のままにしておく。

できない例: td にも背景色がある(縞が隠れる)
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
th, td {
  padding: 6px 10px;
  text-align: left;
}
th {
  background: #0f766e;
  color: #fff;
}
tbody tr:nth-child(even) {
  background: #e4e4e7;
}
td {
  background: #fff;
}
できる例: セルの背景は透明のまま
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
th, td {
  padding: 6px 10px;
  text-align: left;
}
th {
  background: #0f766e;
  color: #fff;
}
tbody tr:nth-child(even) {
  background: #e4e4e7;
}

ホバー行を強調する

上の例では縞のあとに .stripe tbody tr:hover を書いている。
この 2 つは詳細度が等しいため、あとに書いた :hover の側が適用され、マウスを載せた行だけ色が変わる。

逆に :hover を先に書くと、偶数行では縞の色に負けてホバーが効かなくなる。
詳細度が同じ規則を並べるときは、勝たせたい方を後ろに置く。

このコードで動いた?