学完这篇,你能针对不同数据形态的表格,选出最合适的移动端方案,并直接抄走可用的 CSS 与几行 JavaScript。
HTML 表格在手机上最容易出问题:要么把整个页面撑出横向滚动条,要么内容被挤成竖排的一个字一行。下面提供四种方案,按“改动成本从低到高”排列,你可以按场景挑选。
第一步:先确认表格属于哪一类
动手前先分类,这决定了该用哪招:
- 每行是一条独立记录(订单、用户列表):适合卡片化堆叠
第二步:方案一,横向滚动(最省事)
在外面包一层容器,让滚动只发生在容器内,而不是整个页面:
<div class="table-scroll">
<table>...</table>
</div>
.table-scroll{
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.table-scroll table{
min-width: 640px; /* 小于这个宽度就不压扁,改为滚动 */
border-collapse: collapse;
}
再补一个“右侧还有内容”的视觉暗示:
.table-scroll{
background:
linear-gradient(90deg,#fff 30%,rgba(255,255,255,0)) left / 40px 100% no-repeat local,
linear-gradient(270deg,#fff 30%,rgba(255,255,255,0)) right / 40px 100% no-repeat local,
radial-gradient(farthest-side at 0 50%,rgba(0,0,0,.12),transparent) left / 14px 100% no-repeat scroll,
radial-gradient(farthest-side at 100% 50%,rgba(0,0,0,.12),transparent) right / 14px 100% no-repeat scroll;
}
注意:容器上别忘 min-width: 0。如果它处在 flex 或 grid 子项里,默认 min-width:auto 会让表格把父容器顶开,横向滚动直接失效。
第三步:方案二,隐藏次要列
给可牺牲的列加 class,在小屏隐藏:
@media (max-width: 640px){
.col-optional{ display: none; }
th, td{ padding: 8px 6px; font-size: 14px; }
}
注意:只隐藏“能用详情页补回来”的列(如创建时间、备注、操作按钮的次要项)。不要把唯一的主键类信息藏掉,否则用户看不出这行是什么。
第四步:方案三,卡片化堆叠(推荐给记录型表格)
小屏时把每行变成一张卡片,用 data-label 把表头补回每格前面:
@media (max-width: 640px){
.table-card thead{ display: none; }
.table-card, .table-card tbody, .table-card tr, .table-card td{ display: block; width: 100%; }
.table-card tr{
border: 1px solid #e5e5e5;
border-radius: 8px;
margin-bottom: 12px;
padding: 4px 0;
}
.table-card td{
display: flex;
justify-content: space-between;
gap: 12px;
border: 0;
padding: 8px 12px;
}
.table-card td::before{
content: attr(data-label);
color: #888;
flex: 0 0 auto;
}
.table-card td:last-child{ border-bottom: 0; }
}
每格加属性:<td data-label="价格">¥99</td>。手写太累就交给脚本:
document.querySelectorAll('table.table-card').forEach(t => {
const heads = [...t.querySelectorAll('thead th')].map(th => th.textContent.trim());
t.querySelectorAll('tbody tr').forEach(tr => {
[...tr.children].forEach((td, i) => { if (heads[i]) td.dataset.label = heads[i]; });
});
});
注意:卡片化后 <tr> 的 display:block 会让表格语义丢失,屏幕阅读器读不出行列关系。如果站点重视无障碍,给 <table> 保留 role="table"、给单元格保留 role="cell",或干脆只在视觉层做卡片化。
第五步:方案四,Grid 重排做对比表
需要保留行列对应关系时,用 Grid 让小屏变成两列布局:
@media (max-width: 640px){
.table-grid tr{
display: grid;
grid-template-columns: 40% 1fr;
}
.table-grid td{ display: block; }
}
这样左列天然成为“标签列”,不用写 ::before。
第六步:通用细节,别漏了
- 数字列右对齐,加
font-variant-numeric: tabular-nums,竖着读更整齐
- 长单词、URL 加
word-break: break-word,避免撑破格子
- 单元格默认不换行的文本别加
white-space: nowrap;一旦加了,就必须配横向滚动
- 给
table 设 table-layout: fixed 时,务必同时给出各列宽度,否则列宽会平均分配,内容很难看
小结
- 列少先上横向滚动,容器
overflow-x:auto 且注意 min-width:0
- 重要列少就用 媒体查询隐藏次要列,只藏非关键信息
- 记录型表格用 卡片化 +
data-label,表头可用脚本自动写入
- 需要保留行列对比用 Grid 两列重排
- 别忘数字对齐、长串断词、
nowrap 与滚动容器的配套关系