nth-child(odd)和nth-child(even)按父元素所有子元素顺序编号,易受非目标标签干扰;推荐用nth-of-type(odd/even),表格中需限定tbody内使用,并注意可访问性与对比度。

nth-child(odd) 和 nth-child(even) 是最直接的写法
想让表格或列表隔行变色,nth-child(odd) 匹配第 1、3、5… 行,nth-child(even) 匹配第 2、4、6… 行。注意它按父元素下的所有同级子元素**顺序编号**,不只看目标标签类型。
- 如果父容器里混有 、
、,li:nth-child(odd)可能完全不生效——因为第 1 个子元素可能是,根本不是- 更稳妥的写法是用
li:nth-of-type(odd),它只计算同为的兄弟元素- 颜色值建议用 rgba 或 hsl,方便后续微调透明度或明暗,比如
background-color: hsl(210, 8%, 95%)实际用在表格里要注意 和 的影响
表格中如果写了
,它的会占用序号,导致 tbody tr:nth-child(odd)从第 1 行开始算,但视觉上第 1 行其实是表头下方的第 1 行数据——结果第一行数据反而没被选中。- 正确做法是把选择器限定在
内部:tbody tr:nth-child(odd)- 或者统一用
tbody tr:nth-of-type(odd),避免受或注释节点干扰- 若需兼容老版本 IE(
nth-child不支持),得用 JS 动态加 class,或改用:nth-child(2n+1)这种等价写法(IE9+ 支持)遇到嵌套列表或动态插入内容时,nth-child 会“重排”
nth-child每次都重新按当前 DOM 结构实时计算序号。如果往列表中间插入一个新,后面所有元素的序号都会变,原本偶数行的样式可能突然跑到奇数位置上。- 这不是 bug,是预期行为;但如果业务要求“固定行号样式”(比如导出 PDF 时样式必须稳定),就得换思路:服务端渲染时就加好
class="row-odd"/class="row-even" -
前端动态渲染时,可用 JS 在插入后手动重置 class:
element.classList.toggle('even', index % 2 === 0) - 纯 CSS 方案中,
nth-child(2n)和nth-child(2n+1)效果等同于even/odd,但语义更明确,也方便扩展(比如每 3 行一循环就写3n+1)
别忽略可访问性与对比度问题
仅靠背景色区分行,对色觉障碍用户或低亮度屏幕可能失效。WCAG 要求文本与背景对比度至少 4.5:1,而浅灰配浅灰很容易不达标。
- 别用
#f0f0f0配#ffffff——实测对比度只有 1.1:1 - 推荐组合:
background-color: #f8f9fa(文字黑字)对比度约 15:1;或用细边框辅助:border-bottom: 1px solid #e9ecef - 深色模式下记得用
@media (prefers-color-scheme: dark)覆盖背景色,否则浅色背景在暗色系统里会刺眼
、对比度是否达标。漏掉任意一项,都可能让样式在某个环节失效或不可用。 - 或者统一用
- 更稳妥的写法是用










