できない.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 行目として数えられてしまう。

背景色が付かないとき

行に背景色を指定したのに変化が見えないときは、セル側にも背景色が付いていないかを確認する。
テーブルの背景はテーブル本体・行グループ・行・セルの順に重ねて描かれ、セルの背景がいちばん手前に来る。
つまり td に background を指定していると、その下にある行の背景は覆い隠されて見えない。
縞模様を行単位で制御したいなら、セルの背景は透明のままにしておく。

ホバー行を強調する

上の例では縞のあとに .stripe tbody tr:hover を書いている。
この 2 つは詳細度が等しいため、あとに書いた :hover の側が適用され、マウスを載せた行だけ色が変わる。
逆に :hover を先に書くと偶数行では縞の色に負けてホバーが効かなくなる。
詳細度が同じ規則を並べるときは、勝たせたい方を後ろに置く。

この記事は役立ちましたか?