3D 卡片堆叠特效(纯 CSS,悬停扇形展开,角度/间距可调)
3D 卡片堆叠特效:纯 CSS 实现扑克牌式堆叠,悬停时扇形展开并上浮,展开角度、水平间距、上浮高度实时可调,弹性缓动手感自然,零 JS。
效果演示(真实可交互)
🖱 悬停卡片堆 → 3D 扇形展开
完整代码
<div class="scene">
<div class="stack">
<div class="card" style="--i:0">♠ A</div>
<div class="card" style="--i:1">♥ K</div>
<div class="card" style="--i:2">♦ Q</div>
<div class="card" style="--i:3">♣ J</div>
<div class="card" style="--i:4">★ 10</div>
</div>
</div>
.scene { perspective: 900px; }
.stack {
position: relative;
width: 132px;
height: 184px;
transform-style: preserve-3d;
}
.card {
position: absolute;
inset: 0;
border-radius: 14px;
background: #fff;
box-shadow: 0 12px 28px rgba(0,0,0,.45);
transition: transform .5s cubic-bezier(.34, 1.45, .64, 1);
/* 堆叠态:每张卡片依次下移、轻微后仰 */
transform: translateY(calc(var(--i) * 9px)) rotateX(calc(var(--i) * -5deg));
}
.stack:hover .card {
/* 展开态:上浮 + 水平散开 + 扇形旋转 + 纵深 */
transform:
translateY(calc(var(--i) * 26px * -1))
translateX(calc((var(--i) - 2) * 46px))
rotateZ(calc((var(--i) - 2) * 10deg))
translateZ(calc(var(--i) * 26px));
}
核心技巧:给每张卡片写一个 --i 序号(0 起),所有偏移都用 calc() 基于序号推导——中间那张 --i:2 位置不变,两侧对称散开。cubic-bezier(.34, 1.45, .64, 1) 的回弹曲线让展开过程像真实的扇形展开。
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 卡片数量 | 增加/删除 .card | 注意以中间序号为对称轴,奇数张效果最佳 |
| 展开角度 | rotateZ(calc((var(--i) - 2) * 10deg)) | 每张之间的扇形角度 |
| 水平间距 | translateX(calc((var(--i) - 2) * 46px)) | 展开后的横向距离 |
| 上浮高度 | translateY(calc(var(--i) * 26px * -1)) | 悬停时整体抬升幅度 |
| 纵深 | translateZ(calc(var(--i) * 26px)) | 前后错层,增强 3D 层次 |
| 动画时长/缓动 | transition: ... .5s cubic-bezier(...) | 回弹系数 1.45 越大弹得越明显 |
兼容性与性能
- 纯 CSS transform 实现,动画全程 GPU 合成,5 张卡片悬停无任何性能压力
transform-style: preserve-3d在 Chrome/Safari/Firefox/Edge 全支持;iOS Safari 需注意卡片内文字若使用transform嵌套可能触发 z-fighting,可给卡片加backface-visibility: hidden规避- 无 JS、无图片,复制即用;hover 在触屏设备上表现为点击瞬间展开,移动端可改为
:focus或点击切换类名 - 旧浏览器无 3D 支持时退化为「卡片依次下移」的平面堆叠,视觉依然成立
常见问题
Q: 卡片展开后重叠顺序不对怎么办? 3D 空间里由 translateZ 决定前后,序号越大越靠前;想要反向就把 translateZ 的系数改成 calc((4 - var(--i)) * 26px),或配合 z-index: var(--i) 强制排序。
Q: 想换成「展开后始终平铺不倾斜」的样式? 把 rotateZ(...) 项删除、保留 translateX/translateY/translateZ 即可得到「阶梯式平铺」效果,适合做技术栈展示。
Q: 移动端没有 hover 怎么办? 改用点击切换:JS 里给 .stack 切换 .open 类,CSS 把 .stack:hover .card 改成 .stack.open .card,其余不变,代码改动仅一行选择器。
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(缓动曲线)等属性即可,代码中有注释说明。