表格行状态不能直接用tr:hover或:nth-child,因浏览器对tr样式支持有限、hover在Safari/旧Edge中对动态tr失效、nth-child在JS插入后错位;BEM通过显式class(如--pending)由JS控制状态,确保SSR对齐、可访问性(同步tabindex/focus)及CSS作用域隔离。

表格行状态为什么不能直接用 tr:hover 或 :nth-child
浏览器对 tr 的样式支持有硬限制:部分属性(如 flex、position: absolute、transform)在多数版本中完全不生效;:hover 在 Safari 和旧版 Edge 中对动态插入的 tr 常失效;tbody tr:nth-child(odd) 这类选择器在 JS 插入新行后会错位,斑马纹立刻乱序。BEM 不是绕过这些限制,而是帮你避开它们——把状态交还给可编程的 class。
user-list-table__row--pending 这类修饰符该怎么加、加在哪
状态修饰符必须绑定到具体行元素上,且只由 JS 显式控制,不能靠伪类或结构推导:
- HTML 中直接写
<tr class="user-list-table__row user-list-table__row--pending">,不要等 JS 拼接 - JS 触发状态变更时,统一用
element.classList.toggle("user-list-table__row--pending"),避免字符串拼接漏空格 - 服务端渲染(SSR)必须和服务端数据状态严格对齐,比如后端返回
status: "pending",就同步输出--pending类名,否则首屏闪动 - 禁用嵌套修饰符写法:
user-list-table__row--pending--error是非法的,应拆成user-list-table__row--pending user-list-table__row--error
行状态与列职责怎么不打架
行修饰符管「这行整体处于什么业务状态」,列修饰符管「这个单元格承担什么业务角色」,二者正交,互不覆盖:
-
user-list-table__row--pending控制整行背景色、禁用交互、添加 loading 动画 -
user-list-table__cell--status控制该列内图标、文字颜色、tooltip 内容,和行状态无关 - 当两者共存时,CSS 优先级靠 specificity 解决:
.user-list-table__row--pending .user-list-table__cell--status可微调 pending 状态下的状态列表现,但这类规则要极少、极明确 - 避免用
user-list-table__row--pending .user-list-table__cell--actions button这种后代选择器——它破坏了 BEM 的作用域隔离,应该封装为user-list-table__cell--actions--pending(如果动作列在 pending 行下需特殊行为)
为什么 user-list-table__row--selected 必须同步控制 tabindex 和焦点逻辑
仅加样式类无法满足可访问性要求。键盘用户按 Tab 时,焦点不会自动落到带 --selected 的行上,屏幕阅读器也读不出状态变化:
立即学习“前端免费学习笔记(深入)”;
- JS 设置
--selected时,必须同时设置tabindex="0"并调用element.focus() - 移除
--selected时,应清除tabindex,防止焦点陷阱 - 若该行含可聚焦子元素(如按钮),需额外处理
focusin事件,确保父行状态同步更新 - IE11 不支持
Element.matches(":focus-visible"),得用document.activeElement === rowEl回退判断


















