最推荐用display: grid实现自适应商品栅格,核心是grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)),配合gap: 16px控制间距、object-fit: cover防图片变形,并为ie11提供flex降级方案。

用 display: grid 做自适应商品栅格
这是当前最推荐的方案,适合首页、分类页这类多列流式陈列场景。核心不是写死列数,而是让列宽随容器动态伸缩。
-
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))——最小列宽 280px,容器够宽就自动加列;auto-fill和auto-fit行为略有不同:auto-fill会预留空列(哪怕没内容),auto-fit则会收缩空列,实际项目中更常用auto-fit -
gap: 16px统一控制行列间距,比给每个.product加margin-bottom更可靠,能避开 margin 合并问题 - 图片高度不一致?加
.product img { height: 180px; object-fit: cover; },防止拉伸变形;IE11 不支持minmax()和auto-fit,需降级为display: flex; flex-wrap: wrap; flex-basis: 280px
用 display: flex 做横向滚动商品栏
适合“猜你喜欢”“相关商品”这类单行、可滚动、卡片宽度固定的场景,逻辑直白且兼容性好。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 必须三件套:
display: flex+overflow-x: auto+white-space: nowrap,缺一不可;否则卡片会换行而不是滚动 - 每张卡片设
flex: 0 0 240px(不放大、不缩小、固定宽),再配margin-right: 12px;最后一项去边距用.product:last-child { margin-right: 0 },或更稳妥地改用gap: 12px(Safari 14.1+ 支持) - 加
scroll-behavior: smooth提升滚动体验,但注意部分安卓 WebView 不支持
别用 table 做商品列表
表格语义是「二维数据关系」,而商品卡片是独立内容单元,强行套用会导致一堆隐性问题。
- 小屏上容易出现横向滚动、文字折行错乱;JS 批量操作时节点层级深(
tr > td > div > img),结构不统一 - 屏幕阅读器把每个
td当成“单元格数据”,而非“一件商品”,破坏无障碍体验 - 现代布局特性(如
gap、aspect-ratio、flex-wrap)在table里根本没法用,硬 hack 只会让 CSS 越来越臃肿 - 唯一合理使用
table的场景:后台管理页的订单明细、库存报表等真正需要行列对齐的数据
语义化结构和图片占位防抖动
布局只是表层,HTML 结构和资源加载策略直接影响用户体验和可维护性。
- 单品必须用
<article></article>包裹,不是<div> 或 <code><li>;里面嵌套<figure></figure>放主图 +<figcaption></figcaption>放标题/价格,规格用<dl></dl>结构化 - 图片加载慢导致卡片塌陷?优先用
aspect-ratio: 3/4(Chrome 103+、Firefox 98+ 支持);老浏览器 fallback 用伪元素撑开:.product::before { content: ""; display: block; padding-top: 133%; } - 筛选逻辑必须依赖
data-category属性,别靠class解析字符串——class="laptop-pro"会被.laptop误匹配;显隐控制用.hidden类,而非直接改style.display
真实项目里,最常翻车的不是写不出布局,而是把语义、响应式、可访问性和加载体验割裂开处理。比如只顾 grid 写得漂亮,却忘了给图片加占位;或者 flex 滚动流畅了,但筛选时用 class 名做判断,结果上新后批量失效。这些点不在同一层,但全得同步考虑。










