3D 分层卡片组件(CSS 层叠景深卡片,悬停/点击展开可调)
3D 分层卡片组件:CSS preserve-3d 让多层卡片沿 Z 轴按索引错位展开,悬停或点击触发,层间距与倾斜角实时可调,纯 CSS 过渡零 JS 依赖,层次分明景深感强。
效果演示(真实可交互)
🖱 悬停卡片堆(或点击「展开」)让各层沿 Z 轴散开,形成景深
完整代码
思路:把卡片拆成 N 个绝对定位的层,每层用 --i 记录序号;默认所有层叠在一起(translateZ(0)),悬停或展开时每层按 translateZ(--i × 层间距) 沿 Z 轴依次散开。容器本身带 rotateX/rotateY 的俯视角,散开后的深度差即被透视放大,形成清晰的立体层次。
<div class="scene">
<div class="stack" id="stack" data-open="0">
<div class="layer layer--bg" style="--i:0"><span>背景层</span></div>
<div class="layer layer--img" style="--i:1"><span>🖼 图片层</span></div>
<div class="layer layer--txt" style="--i:2"><span>✍ 文本层</span></div>
<div class="layer layer--btn" style="--i:3"><span>🔘 按钮层</span></div>
<div class="layer layer--top" style="--i:4"><span>💎 顶层</span></div>
</div>
</div>
.scene { height: 420px; perspective: 1000px; display: flex; align-items: center; justify-content: center; }
.stack {
position: relative; width: 250px; height: 330px;
transform-style: preserve-3d; /* 层间保持空间关系 */
transform: rotateX(10deg) rotateY(-16deg); /* 俯视角,暴露深度 */
transition: transform .5s;
}
.layer {
position: absolute; inset: 0;
border-radius: 18px;
display: flex; align-items: center; justify-content: center;
color: #fff;
transform: translateZ(0); /* 默认收拢 */
transition: transform .55s cubic-bezier(.34, 1.3, .5, 1);
}
.stack:hover .layer,
.stack[data-open="1"] .layer {
transform: translateZ(calc(var(--i) * 34px)) /* 逐层沿 Z 散开 */
translateY(calc(var(--i) * -10px));/* 附带轻微上移 */
}
// 点击展开/收起(触屏无 hover 时的替代交互)
toggle.addEventListener('click', () => {
const open = stack.dataset.open === '1';
stack.dataset.open = open ? '0' : '1';
});
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 层间距 | --i × 34px | 每层沿 Z 的错位量,演示中 0-80px 可调 |
| 倾斜角 | rotateX(10deg) rotateY(-16deg) | 俯视角度越大,深度越明显 |
| 展开触发 | :hover 与 data-open | 桌面悬停、触屏点击双通道 |
| 上移幅度 | translateY(--i × -10px) | 层叠展开时轻微的阶梯错落 |
| 过渡曲线 | cubic-bezier(.34, 1.3, .5, 1) | 带回弹的展开手感 |
兼容性与性能
- 全组件 5 层共 5 个元素,transform 过渡全部由 GPU 合成,动画极省资源
- 展开/收拢为一次性过渡,不涉及逐帧计算,移动端同样流畅
- Chrome / Safari / Firefox / Edge 全支持;iOS Safari 保留
-webkit-transform-style: preserve-3d - 悬停与点击双触发设计,触屏设备无需 hover 也能完整演示
- 各层为真实文档元素,内容可放任意 HTML,无障碍友好
- 不支持的旧浏览器中退化为单张卡片显示,内容不丢失
常见问题
Q: 展开后层与层看起来没有深度、仍是平面? 容器必须同时具备三点:transform-style: preserve-3d、带 rotateX/rotateY 的俯视角、以及 perspective(在容器或父级上)。三者缺一,Z 轴错位就无法被透视观察到。
Q: 悬停触发和点击触发会互相干扰吗? 不会。:hover 只管桌面悬停,data-open 由按钮控制;两者共用同一套展开规则,谁触发都显示同一结果,触屏上按钮是唯一入口。
Q: 层数多了以后性能下降? 分层卡片层数建议控制在 8 层以内。层数过多时,可把 will-change: transform 加到 .layer 上提前建层,减少首帧卡顿。
Q: 可以商用吗? 可以。本组件为粤喵自研原创代码,免费商用无需署名,层数、颜色、层间距均可自由定制。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。