卡片容器必须设宽高或视觉锚点才能显形,否则空默认无尺寸、透明、不占空间;语义标签需按内容实质选用,内部结构须用Flex column或Grid控制垂直流,响应式列数应使用grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))实现。

纯 <div> 不是卡片,没样式就不可见;标准结构不是“怎么写标签”,而是“怎么让卡片在字体加载、图片异步渲染、内容动态填充时不跳动”。
<h3>卡片容器必须设宽高或视觉锚点才能显形</h3>
<p>空 <code><div class="card"></div> 默认无尺寸、透明、不占空间。浏览器不会凭空画出一个“卡片”。要让它可见,至少得有以下之一:
-
width+padding(如width: 280px; padding: 16px;) -
background-color或border(哪怕border: 1px solid transparent也能触发渲染) -
aspect-ratio(配合img或占位元素,防高度塌陷)
漏掉这一条,后面所有布局都白搭——你看到的“空白”,其实是它根本没渲染出来。
别用 <section></section> 或 <article></article> 强套卡片
语义标签不是装饰品。<article></article> 表示独立可分发的内容单元(如博客条目、商品详情页),<section></section> 表示文档章节。如果只是仪表盘里的指标块、空操作入口、或者轮播图占位项,用 <div> 更准确。<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
<p>常见误用:</p>
<ul>
<li>把所有卡片都套 <code><article></article>,结果屏幕阅读器反复播报“article”打断节奏
<section></section> 替代视觉分组,但没配 aria-labelledby,无障碍失效role="article",却没补 tabindex="0",键盘无法聚焦真正该加语义的,是那些用户可能想分享、收藏、订阅的内容单元。
内部结构必须用 Flex column 或 Grid 控制垂直流
卡片内标题、描述、按钮堆叠错位,90% 是因为用了 margin 或 position: absolute 控制间距。这会导致:
- 文字截断后高度突变,整行卡片上下跳动
- 图片加载延迟时,按钮位置飘移
- 不同字体加载完成时间不一致,行高重排
正确做法是让卡片自身成为弹性容器:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-body {
flex-grow: 1;
}
.card-footer {
margin-top: auto;
}
这样,无论标题几行、描述多长、按钮是否显示,底部按钮永远贴底,主体区域自动吸满剩余空间。
响应式列数必须靠 grid-template-columns: repeat(auto-fit, minmax(...))
写死 grid-template-columns: repeat(3, 1fr) 或用 float / inline-block 模拟三列,小屏下必然压扁文字、撑破容器、甚至触发横向滚动。
真正可控的响应式列数写法只有一条:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
其中:
-
280px是移动端最小可读宽度(低于它就自动退单列) -
auto-fit会收缩空轨道,避免小屏出现“看不见的列”把卡片挤窄 -
gap管所有间距,不用再给.card加margin,否则间距翻倍
这个组合不需要媒体查询,也不依赖 JS,但必须配合卡片内部的 flex-direction: column 和图片的 object-fit: cover 才真正稳。
最难的从来不是写出第一张卡片,而是让 20 张卡片在字体未加载、图片懒加载、服务端数据分批返回时,高度始终一致、不跳动、不重排——这需要 aspect-ratio 占位、contain: layout style 锁定渲染边界、以及所有文本截断用 -webkit-line-clamp 而非固定 height。


















