
当卡片数量不固定且需在限定高度容器中自动填满可视区域时,可通过为非首张卡片设置负 margin-top 实现视觉上的均匀分布,规避 gap 不支持负值的限制。
当卡片数量不固定且需在限定高度容器中自动填满可视区域时,可通过为非首张卡片设置负 `margin-top` 实现视觉上的均匀分布,规避 `gap` 不支持负值的限制。
在 Flex 布局中,gap 属性虽能便捷控制子项间距,但不支持负值;而 margin-top: auto 也无法产生负向推挤效果。面对“卡片数量动态变化、必须全部显示在固定高度视口内且视觉上均匀分布”的需求(如 Figma 示例中的垂直堆叠动画),直接依赖标准间距属性难以达成目标。此时,负外边距(negative margin)是简洁有效的解决方案。
核心思路是:
- 将卡片容器设为
flex-column,居中对齐; - 所有卡片保持统一高度(建议使用相对单位如
vh,便于响应式适配); - 对除第一张外的所有卡片,统一施加负
margin-top,使其向上叠加,形成紧凑、等距的层叠效果。
以下为可直接运行的完整示例:
<div class="cards-wrapper"> <div class="card"><h3>Card 1</h3></div> <div class="card"><h3>Card 2</h3></div> <div class="card"><h3>Card 3</h3></div> <div class="card"><h3>Card 4</h3></div> <div class="card"><h3>Card 5</h3></div> </div>
.cards-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh; /* 或具体高度,如 50vh */
width: 100%;
max-width: 332px;
margin: 0 auto;
padding-top: 200px; /* 可按需调整顶部留白 */
}
.card {
background: linear-gradient(179deg, #e5e2da 0%, #8b8b8b 100%);
width: 100%;
height: 22vh; /* 推荐使用 vh 单位,确保高度随视口缩放 */
border-radius: 20px;
box-shadow: 0 0 4px 1px #ababab;
display: flex;
align-items: center;
justify-content: center;
color: #333;
font-weight: 600;
}
.card:not(:first-child) {
margin-top: -12vh; /* 关键:负值决定重叠密度,需根据 card 高度微调 */
}
✅ 关键注意事项:
- 负
margin-top的绝对值应略小于单张卡片高度(例如height: 22vh→margin-top: -12vh),以保留适当视觉间隙; - 若卡片内容高度不固定,建议将
.card设为min-height并配合flex内部对齐,避免布局塌陷; - 在移动端需测试
vh单位兼容性(iOS Safari 中100vh可能受地址栏影响),必要时可用100dvh替代; - 此方案不改变 DOM 结构与卡片自身尺寸,完全通过 CSS 控制视觉分布,语义清晰、维护成本低。
该方法已在实际项目中验证:无论卡片是 2 张还是 8 张,均能在固定容器内实现平滑、自适应的垂直填充效果,完美匹配设计稿中的动态分布需求。










