直接用 table 在手机上会出问题,因为其默认横向流式布局在小屏下易溢出或换行错乱,且无自动表头关联;需手动为每个 td 添加 data-label,并配合媒体查询重置 display 为 block、隐藏 thead、用 ::before 显示标签。

为什么直接用 table 在手机上会出问题
因为 table 默认是横向流式布局,列宽由内容撑开,小屏下必然溢出或文字换行错乱。浏览器不会自动“折行”表头和数据,也不会帮你标注哪一列对应什么字段——你看到的只是挤在一起的 td,没上下文。这不是 bug,是 HTML 表格的原始设计逻辑决定的。
data-label 必须手动加在每个 td 里
别指望 JS 自动生成或 CSS 能读取 th 文本回填——CSS 的 ::before 只能读取元素自身的属性值。所以必须在写 HTML 时就为每个 td 显式设置 data-label:
<tr> <td data-label="订单号">ORD-2026-789</td> <td data-label="客户">李四</td> <td data-label="状态">已发货</td> </tr>
- 值要简洁,比如
"状态"比"当前订单处理状态"更适合移动端显示 - 不能依赖 JS 注入:SSR 或静态页面里没 JS 时照样得生效
- 如果用模板引擎(如 Vue/React),确保
data-label是硬编码或从列配置映射而来,而非运行时推导
媒体查询里 display: block 的作用对象不能漏
只给 tr 设 display: block 不够,td 还会保持表格单元格行为。必须一并重置整套结构:
@media (max-width: 768px) {
table, thead, tbody, th, td, tr { display: block; }
thead { display: none; }
tr { margin-bottom: 0.8rem; }
td {
position: relative;
padding-left: 100px;
border: none;
}
td::before {
content: attr(data-label) ": ";
position: absolute;
left: 0;
font-weight: 600;
width: 90px;
}
}
-
thead必须显式设为display: none,仅靠position: absolute移走不可靠(部分 Android 浏览器仍占位) -
th也要参与display: block,否则可能触发怪异盒模型计算 -
td::before的width建议固定,避免不同标签长度导致左对齐混乱
横向滚动容器是更省事但有代价的备选方案
当表格列多、字段长、或含操作按钮时,堆叠布局会让卡片高度失控,用户要反复滚动才能看全一行。这时不如用滚动容器:
立即学习“前端免费学习笔记(深入)”;
<div class="table-container"> <table>...</table> </div>
.table-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }
- 不用改 HTML 结构,
data-label和媒体查询全可删 - 注意:iOS Safari 对
overflow-x: auto在body直接子元素上支持不稳定,务必包一层div - 滚动条默认样式难看,如需美化得用 JS 模拟或接受原生表现
- 屏幕阅读器可能无法正确通告“可横向滚动”,对无障碍不友好
真正麻烦的不是写法,而是判断:哪些列该保留、哪些字段值得用 data-label 标注、滚动容器是否掩盖了信息优先级问题——这些没法靠 CSS 自动解决。



















