display: contents + grid 是最可控的响应式表格方案,因其由 CSS Grid 统一控制布局,避免了 display: block 切换导致的对齐失效、边框堆叠和文字挤压等问题,但需规避 IE 不支持、colspan 失效及 Sass 编译时静态限制三大缺陷。

直接用 display: contents + grid 是目前最可控的响应式表格方案,但必须绕开 IE 兼容、colspan 失效和编译时静态限制这三个硬伤。
为什么 display: contents + grid 比 @media 切换 display: block 更稳
手动切 display: block 会导致 th/td 垂直对齐失效、边框堆叠、文字挤在一起,还得额外处理 padding 拆向上下、border 改用 border-bottom、text-align 统一左对齐——漏一条就错位。而 display: contents 让 tr 和 td 脱离渲染流,由父级 table 元素用 display: grid 统一控制布局,行列顺序、跨列逻辑全由 CSS Grid 规则驱动。
- 必须给
table元素设display: grid,否则contents不生效 -
tr设display: contents,td设grid-column: span 1,才能被 grid 容器捕获 - 别给
td写grid-row,它会破坏自然流顺序;用grid-auto-flow: row更可靠 - IE 完全不支持
display: contents,需 fallback:用display: block+:nth-child()模拟行/列,或加data-label配合::before显示表头
用 @function make-grid-cols 生成 grid-template-columns
Sass 无法运行时推导列数,所谓“动态”其实是预设规则映射:把「每行显示 N 列」转成 repeat(N, minmax(120px, 1fr))。这个函数要封装宽度下限和重复逻辑,避免在每个断点里硬写字符串。
- 函数定义:
@function make-grid-cols($count, $min: 120px) { @return repeat(#{$count}, minmax(#{$min}, 1fr)); } - Sass 3.5+ 才支持
minmax()直接参与计算,旧版本得用插值:#{'minmax(' + $min + ', 1fr)'} - 调用时绑定类名更可控,比如
.table--cols-3对应$count: 3,比套多层@media更易维护 - 别用
flex模拟表格——它无法保证行列对齐,colspan会彻底失效
用 @mixin responsive-table 封装整套重置规则
纯靠 display: contents 不够,小屏下仍需补位:自动注入表头文字、重设盒模型、适配可访问性。这些不能零散写,得用 mixin 统一收口。
立即学习“前端免费学习笔记(深入)”;
- 提前定义列名数组:
$columns: (name, email, role, status),再用@each生成td[data-label="#{$col}"]::before规则 - 配合 HTML:
<td data-label="email">user@example.com</td>,屏幕阅读器能读取data-label(建议加aria-label更稳妥) - 若列名含空格或特殊字符,SCSS 字符串拼接需转义;生产环境推荐用
nth-child()+attr()替代,减少 DOM 属性污染 - 别只改
display,同步处理三类属性:盒模型(padding-top/bottom)、边框(border-bottom)、文字对齐(统一text-align: left)
真正麻烦的不是写对一次循环,而是当设计系统从 12 列升级到 24 列时,$grid-max-columns、percentage 分母、grid-column-start 上限、断点内循环范围——所有地方都得同步改,漏一个就崩。


















