必须直接替换嵌套表格而非修复:因其导致屏幕阅读器无法建立父子表头关系、scope/headers失效、键盘导航卡死;根本原因是DOM解析逻辑断层,非渲染问题。
直接替换掉嵌套表格,别修它。历史遗留框架里用 <table> 套 <table> 的结构,本质是语义坍塌——屏幕阅读器无法建立父子表头关系,scope 失效,headers 属性失效,连键盘导航都会在子表内部卡死。
不是渲染问题,是解析逻辑断层。浏览器能画出两层表格,但辅助技术依赖 DOM 结构推导数据关系。当一个 <td> 里塞进完整 <table>,父表的 <th scope="col"> 就再无法“覆盖”到子表的 <td> 上;子表自身又缺少独立 <caption> 和 <thead>,变成一堆无上下文的单元格。
<input>,因为它们被判定为“非表格数据流的一部分”aria-labelledby 或 headers 指向子表内 ID 时,多数屏幕阅读器直接忽略——不报错,也不生效如果 CMS 输出不可改、邮件模板受限、或第三方 iframe 内容无法控制,只能做最小干预。核心是让子表“自证身份”,切断对父表语义的依赖。
<table> 必须带 <caption>,且文本要说明用途,比如 <caption>订单 #12345 的明细项</caption>
<thead>,哪怕只有一行,且每列 <th> 显式加 scope="col"
colspan/rowspan,它们在嵌套中会放大定位偏差role="region" 和唯一 aria-label,例如 aria-label="嵌套明细表格",让屏幕阅读器把它当独立区块处理真正可行的解法不是“修表格”,而是用现代布局接管渲染权,同时保持 HTML 表格语义不变——即视觉上仍是表格样式,DOM 结构却可访问。
立即学习“前端免费学习笔记(深入)”;
<table> 改为 <div role="table">,每个 <tr> 改为 <div role="row">,<td> 和 <th> 改为 <div role="cell"> 或 <div role="columnheader">
display: grid; grid-template-columns: 1fr 2fr 1fr;,子区域用 grid-column: span 3 拉满宽度<caption>、<thead>、scope 和 headers,只是换掉了容器标签——语义全在,渲染由 Grid 接管rowheader 和 gridcell 角色是否正确暴露最常被忽略的一点:即使你用了 role="table",也必须手动实现键盘导航支持(ArrowRight/Left 移动单元格,Enter 编辑),否则键盘用户依然卡住。这不是可选项,是可访问性的硬门槛。