表格行高亮不能只靠:hover,因:hover仅作用于当前td/th,无法影响整行tr;:focus-within通过子元素聚焦触发父级样式,需为每个td/th设tabindex并配合tr:focus-within实现行高亮。

表格行高亮为什么不能只靠 :hover?
因为鼠标移入单元格时,:hover 只能选中当前 <td> 或 <code><th>,没法自动把整行 <code><tr> 拉进来——除非你给每个 <code><td> 都写一遍 <code>tr:hover td,但这样列高亮又没法做。而 :focus-within 的关键价值在于:只要某个子元素获得了焦点(比如输入框、按钮、或通过 tabindex 聚焦的元素),父容器就能响应。所以真正可行的路径是:让每行/每列的单元格「可聚焦」,再用 :focus-within 向上影响 <tr> 和 <code><tbody>(或包装列的结构)。
<h3>如何让 <code><tr> 响应行内任意单元格聚焦?
<p>直接给 <code><tr> 加 <code>tabindex 不可靠(部分浏览器不支持对 <tr> 的聚焦,且语义错误)。正确做法是确保每个 <code><td> 或 <code><th> 可聚焦:
<ul><li>给每个 <code><td> 添加 <code>tabindex="0"(仅当需要键盘导航时才必须;若仅需鼠标触发,可用 tabindex="-1" + JS .focus())
tr:focus-within { background-color: #f0f8ff; }:focus-within 会穿透嵌套,所以即使单元格里有 <input> 或 <button></button>,只要它们获得焦点,<tr> 仍会匹配
<li>别忘了重置默认焦点轮廓:<pre class='brush:php;toolbar:false;'>td:focus { outline: none; }</pre>,否则视觉干扰大</li>
<h3>列高亮为什么必须用额外 wrapper?</h3>
<p>CSS 没有原生的「列选择器」,<code>:focus-within 也不能跨兄弟元素向上作用到 <colgroup></colgroup> 或 <thead>。所以得手动为每一列建一个可聚焦的上下文:
<ul><li>在 <code><thead> 中,给每个 <code><th> 加 <code>tabindex="0",并用 data-col="0" 标记列索引
<tbody> 外层包一个 <code><div class="table-col-context">,再用 JS 把每列的 <code><td> 按列号归组,插入对应列 wrapper 中(或者用 CSS Grid 模拟列容器,但兼容性差)
<li>更轻量的做法:用 <code>nth-child(n) 配合 :focus-within 在 <thead> 触发后,强制同列所有 <code><td> 高亮:<pre class='brush:php;toolbar:false;'>th:nth-child(2):focus-within ~ tbody td:nth-child(2), th:nth-child(2):focus-within { background-color: #e6f7ff; }</pre> ——但这要求 HTML 结构严格线性,且无法响应 tbody 内部单元格聚焦
<li>实际项目中推荐 JS 辅助:监听 <code>focusin,读取 cellIndex,然后给整列加临时 class
:focus-within 在表格里的兼容性与陷阱
它在 Chrome 65+、Firefox 61+、Safari 15.4+ 支持良好,但 Edge 16–18 有 bug:对动态插入的聚焦元素响应延迟或失效。另外几个易踩的坑:
立即学习“前端免费学习笔记(深入)”;
<table> 默认是 display: table,而 <code>:focus-within要求父元素是「流式容器」,某些重置样式(如display: block)会让它失效- 如果单元格里有
contenteditable="true",聚焦时可能不触发:focus-within(取决于浏览器是否视其为可聚焦元素),建议统一用tabindex - 移动端 Safari 对
tabindex的处理较保守,纯鼠标悬停场景下,最好搭配:hover回退:tr:hover, tr:focus-within { background-color: #f0f8ff; } - 键盘用户 tab 到某单元格时,整行高亮是好的,但列高亮若依赖 JS,务必确保
focusin事件能捕获到cellIndex,而不是只看event.target的位置
最麻烦的其实是列高亮的 DOM 结构约束——没有天然的列容器,所有「列级」操作最终都绕不开 JS 定位或预设的列索引绑定。这点容易被低估。


















