table不该用于产品展示布局,因其语义错误、响应式失效、可访问性断裂;应选用grid实现多列自适应栅格,或flex实现横向滚动,二者均支持图片占位防抖动与无障碍语义。

table 不该用于产品展示布局。
它语义错误、响应式失效、可访问性断裂,且现代浏览器中维护成本远高于收益。哪怕你只写三行两列,只要不是二维结构化数据(比如价格对比表、课程表),就别碰 table。
为什么用 table 做商品卡片一定会翻车
常见错误现象:移动端横向滚动、图片加载时卡片塌陷、屏幕阅读器把“加入购物车”按钮读成“第3列第2行”,SEO 抓取不到商品标题层级。
根本原因在于:table 强制按行列关系解析内容,而商品卡片是独立语义单元,不是“行×列”的交叉数据。
- 写
<table><tr><td><div class="product">...</div></td></tr></table>,等于给每个商品套上一层语义枷锁 -
colspan/rowspan在响应式断点下完全失控,一加就错位 - 所有现代 CSS 布局特性(
gap、aspect-ratio、flex-wrap)在table内部行为异常或不生效
真正该用的两个布局方案:Grid 和 Flex
选哪个,取决于你要实现的形态:
- 多列自适应栅格(首页商品列表、分类页)→ 用
display: grid - 单行横向滚动(“猜你喜欢”、“浏览历史”)→ 用
display: flex
二者都支持图片占位防抖动、统一间距控制、无障碍语义保留,且一行 CSS 就能 fallback 到老浏览器。
示例(Grid 栅格):
/* HTML 结构保持语义清晰 */ <section class="product-grid"><article class="product">...</article><article class="product">...</article></section>
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.product img {
width: 100%;
height: 180px;
object-fit: cover;
}
图片加载抖动怎么破?提前占位是硬要求
这不是“样式问题”,是 DOM 渲染节奏问题。异步加载的 <img> 初始高度为 0,导致卡片突然收缩,用户正在滑动就会跳一下。
- 现代方案:给
.product加aspect-ratio: 3/4(Chrome 103+、Firefox 98+) - 兼容方案:用伪元素撑开容器,
.product::before { content: ""; display: block; padding-top: 133%; },再把图片设为position: absolute - 最稳妥方案:直接在
<img>上写width="300" style="max-width:90%",浏览器会按比例预留空间
IE11 兼容怎么办?别硬扛 table,换 Flex fallback
grid-template-columns: repeat(auto-fill, minmax(...)) 在 IE11 完全不识别,但你不需要退回到 table。
- 用
@supports not (display: grid)包一层display: flex+flex-wrap: wrap - 每张卡片设
flex: 0 0 240px,配合gap或margin-right/bottom - 关键:父容器必须有明确宽度(如
max-width: 1200px),否则 IE11 下flex-basis计算失准
复杂点不在写法,而在是否意识到:商品展示的本质是「语义化内容流」,不是「表格数据」。一旦混淆这个前提,后面所有样式、交互、可访问性补救都是徒劳。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











