tr:hover 直接加背景色无效是因为 tr 本身不渲染背景,其背景会被 td/th 子元素覆盖;需同时设置 tr:hover td 和 tr:hover th 的背景色,并确保 td/th 原始背景为 transparent 或未声明。
多数情况下不是写法错,而是 tr 本身不渲染背景——它的背景会被子元素(比如 td、th)的背景覆盖。浏览器默认把 tr 当作“透明容器”,即使你给 tr:hover 设了 background-color,只要 td 没设透明背景,就完全看不见效果。
解决办法是让单元格继承或响应行的 hover 状态:
tr:hover td 和 tr:hover th 显式设置背景色td/th 原始背景为 transparent 或无声明(避免覆盖)border-collapse: 
collapse,还要注意边框叠加可能遮挡颜色过渡老版本 IE(IE8 及以下)不支持 tr:hover,但现代项目基本不用考虑。真正容易出问题的是选择器优先级和嵌套结构:
class="data-table"),建议用 .data-table tr:hover td 而非泛用 tr:hover td,避免意外影响其他表格td 内有内联样式或 !important 背景声明,hover 效果会被强制覆盖tr 和 td
当已有 tbody tr:nth-child(even) 这类斑马纹时,hover 颜色必须比条纹色更明确,否则视觉上会“跳变”或失效:
.table-striped tbody tr:nth-child(even) td {
background-color: #f9f9f9;
}
.table-striped tbody tr:hover td {
background-color: #e3f2fd !important; /* 强制覆盖条纹 */
}关键点:
!important 是合理且常见的做法,因为 :nth-child 的优先级通常低于 :hover 组合选择器,但实际计算中可能被绕过tr 背景,仍得同步作用到 td 和 th
iOS Safari 和部分 Android 浏览器在非链接/按钮元素上对 :hover 支持不稳定,点击后才触发、或根本不触发。这不是 bug,是规范行为。
稳妥方案是加一层 JS 响应:
document.querySelectorAll('table tr').forEach(row => {
row.addEventListener('touchstart', () => {
row.classList.add('hover');
});
row.addEventListener('touchend', () => {
row.classList.remove('hover');
});
});再补一条 CSS:
tr.hover td, tr:hover td {
background-color: #e3f2fd;
}这样 PC 和移动都能一致生效。注意别漏掉 touchcancel 防止状态残留,真实项目中建议用 pointerdown/pointerup 替代以兼容更多设备。
hover 的边界其实很窄:它依赖渲染树层级、样式优先级、设备输入模型。稍微嵌套深一点、加个 position: relative、甚至用了 will-change,都可能让背景“消失”。动手前先检查 computed styles 里的 background-color 是否真被应用到 td 上。