如何实现堆叠式卡片垂直滚动效果
如何实现堆叠式卡片垂直滚动效果
嘿,这个堆叠式卡片的垂直滚动效果我之前折腾过好几次,其实用CSS加一点点JS(或者纯CSS新特性)就能轻松实现!下面给你拆解具体的实现思路和示例代码,你可以直接拿去改:
一、基础实现方案(CSS + 少量JS)
这种方案兼容性好,适合大多数场景,核心思路是初始让卡片堆叠在一起,监听滚动事件动态调整卡片位置。
1. 先搭HTML结构
就是一个滚动容器套若干卡片:
<div class="stack-scroll-container"> <div class="stack-card"> <h3>卡片 1</h3> <p>这是第一张堆叠卡片的内容,随便写点啥都可以~</p> </div> <div class="stack-card"> <h3>卡片 2</h3> <p>第二张卡片的内容,堆叠的时候只会露出一小部分哦</p> </div> <div class="stack-card"> <h3>卡片 3</h3> <p>第三张卡片,滚动到对应位置就会展开啦</p> </div> <div class="stack-card"> <h3>卡片 4</h3> <p>最后一张卡片,完全展开后就和普通滚动一样啦</p> </div> </div>
2. CSS核心样式
给容器固定高度并开启垂直滚动,初始让卡片堆叠:
.stack-scroll-container { height: 450px; /* 自定义容器高度 */ overflow-y: auto; padding: 20px; background-color: #f5f5f5; } .stack-card { height: 200px; /* 自定义卡片高度 */ background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 20px; transition: transform 0.3s ease; /* 加个过渡动画更丝滑 */ } /* 初始堆叠:除了第一张,其他卡片向上偏移,形成堆叠效果 */ .stack-card:nth-child(n+2) { transform: translateY(-120px); }
3. JS监听滚动调整位置
当用户滚动时,让堆叠的卡片逐步展开:
const container = document.querySelector('.stack-scroll-container'); const cards = document.querySelectorAll('.stack-card'); container.addEventListener('scroll', () => { const scrollTop = container.scrollTop; cards.forEach((card, index) => { if (index === 0) return; // 第一张卡片保持不动 // 计算偏移量:滚动越多,偏移越小,直到完全展开 const maxOffset = 120; // 和CSS里的初始偏移量保持一致 const currentOffset = Math.max(maxOffset - scrollTop * 0.8, 0); card.style.transform = `translateY(-${currentOffset}px)`; }); });
二、纯CSS进阶方案(滚动驱动动画)
如果你的目标浏览器支持CSS滚动驱动动画(现在Chrome、Firefox、Edge都支持了),可以用纯CSS实现,不用写JS:
.stack-scroll-container { height: 450px; overflow-y: auto; padding: 20px; background-color: #f5f5f5; /* 绑定容器的滚动作为动画时间线 */ scroll-timeline-name: --stack-scroll; scroll-timeline-axis: y; } .stack-card { height: 200px; background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 20px; } /* 给每张卡片设置滚动触发的动画 */ .stack-card:nth-child(2) { animation: unstack 1s linear; animation-timeline: --stack-scroll; animation-range: 0 150px; /* 滚动0到150px时执行动画 */ } .stack-card:nth-child(3) { animation: unstack 1s linear; animation-timeline: --stack-scroll; animation-range: 100px 250px; } .stack-card:nth-child(4) { animation: unstack 1s linear; animation-timeline: --stack-scroll; animation-range: 200px 350px; } /* 堆叠到展开的动画关键帧 */ @keyframes unstack { from { transform: translateY(-120px); } to { transform: translateY(0); } }
三、小优化建议
- 可以给堆叠的卡片加层级阴影,比如上面的卡片阴影更重一点,增强立体感;
- 调整动画的
ease函数,比如用ease-in-out让过渡更自然; - 如果卡片高度不固定,可以用JS动态计算初始偏移量,适配不同内容。
备注:内容来源于stack exchange,提问作者wch
相关产品推荐
相关产品推荐

