用 transform + z-index 实现纸牌堆叠与洗牌动画:图片需绝对定位重合,z-index 从底到顶递增;飞出时用 translate3d 触发硬件加速,配合不同延迟、位移、旋转及 cubic-bezier 曲线模拟真实惯性。

用 transform + z-index 控制每张图片的初始叠放顺序
多张图片要像纸牌一样堆叠,核心是让它们定位重合但 z-index 逐层递减。绝对定位是必须的,否则无法精确叠放;z-index 必须设为不同整数,且从底到顶递减(比如第1张 z-index: 1,第2张 z-index: 2…反而会遮住前面的——人眼看到的“最上层”其实是数值最大的那个)。别依赖默认层叠顺序,浏览器对无 z-index 的同级元素渲染不稳定。
常见错误:z-index 全设成同一值,或只靠 order(对非 flex 容器无效);还有人用 opacity 模拟叠放,结果动画一动就穿帮。
- 给容器加
position: relative,所有图片设position: absolute; top: 0; left: 0; - 用 JS 动态设置每张
<img>的style.zIndex = i(i 从 0 开始递增),确保最“底下”的牌数值最小 - 如果图片数量固定,CSS 里写死也行:
.card:nth-child(1) { z-index: 1; }、.card:nth-child(2) { z-index: 2; }……但注意::nth-child按 DOM 顺序,不是视觉顺序
飞出动画必须用 transform: translate3d() 触发硬件加速
单纯用 left/top 动画会导致卡顿,尤其在移动设备上。只有 transform(特别是带 translate3d(0,0,0))能触发 GPU 加速。洗牌效果本质是每张牌走不同路径:有的向左上抛,有的向右下甩,有的带旋转——这些全靠 transform 组合实现。
容易踩的坑:transition 写在父容器上(失效),或者给所有牌用同一个 transition 时间(结果像捆在一起弹出去);还有人用 animation 但没配 animation-fill-mode: forwards,动画一结束就弹回原位。
- 每张图片单独加
transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);(这个贝塞尔曲线更接近真实抛掷惯性) - 出发时批量改
style.transform,例如:img.style.transform = 'translate3d(-120px, -80px, 0) rotate(-12deg)'; - 避免同时修改
top+left+transform,浏览器会降级到软件渲染
洗牌随机性靠 Math.random() + 不同延迟和位移偏移
真洗牌不是“每张都乱飞”,而是有规律的混乱:顶部几张偏移小、延迟短;底部几张偏移大、延迟长——模拟手抖+纸牌摩擦。用纯 CSS @keyframes 很难做到每张独立参数,JS 控制更直接。
典型翻车现场:所有图片 setTimeout 同一个毫秒值,结果还是齐刷刷飞出去;或者位移全用 Math.random() * 200,导致有些牌飞出屏幕外看不见。
- 延迟建议范围:
delay = 50 + i * 30(i 是索引,保证错峰出发) - 水平位移控制在 ±150px 内,垂直 ±100px,旋转 ±15deg,避免失控
- 加个轻微缩放变化增强真实感:
scale(0.95 + Math.random() * 0.1) - 别忘了重置状态:动画结束后把
transform清空或设回none,否则下次再触发会累加
IE 和旧版 Safari 下 translate3d 可能失效
IE10+ 和 Safari 9+ 支持 translate3d,但 IE10 对 transform 的 z-index 层叠逻辑有 bug:即使设了不同 z-index,仍可能按 DOM 顺序渲染。Safari 旧版本则对 cubic-bezier 支持不全,动画会变线性。
这不是“要不要兼容”的问题,而是用户真会遇到——比如内部系统还在用 IE11,或者 iOS 12 设备访问。
- 检测是否支持 3D transform:
const has3d = window.CSS && CSS.supports('transform', 'translate3d(0,0,0)');,不支持时降级为translate()+transition - IE 下强制开启硬件加速的 hack:
transform: translateZ(0);(比 translate3d 更兼容) - 所有
transform值必须带单位,rotate(12)错,rotate(12deg)对;IE 对单位缺失极其敏感
真实洗牌动画最难的不是让图飞起来,是让它们飞得“像被人手甩出去”——起手有微顿、中途有惯性、落地有余震。这些细节全藏在延迟差、贝塞尔曲线、以及每张牌 transform 的微小差异里。少调一次 Math.random() 的范围,就可能飞出屏幕。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











