如何复刻Wix模板中的卷帘式滚动揭示效果?
如何复刻Wix模板中的卷帘式滚动揭示效果?
我明白你要的效果——就是那个hero区域像卷帘一样向上滑出,下面的内容全程纹丝不动,等卷帘彻底消失后,页面才恢复正常滚动对吧?之前你用animation-timeline: scroll()的问题在于,文档本身的滚动会同时带动下方内容,导致两者动效错位。下面给你一套可行的实现方案:
第一步:梳理清晰的HTML结构
先把卷帘层(原hero区域)和下方内容层明确分开,结构越简洁越好:
<!-- 卷帘层,初始覆盖在所有内容上方 --> <div class="shutter"> <h1>你的Hero标题</h1> <p>Hero区域的描述文案</p> </div> <!-- 下方所有页面内容的容器 --> <div class="page-content"> <section class="content-block"> <h2>第一部分内容</h2> <p>这里是页面的正常内容,初始时会被卷帘层遮挡</p> </section> <section class="content-block"> <h2>第二部分内容</h2> <p>更多页面内容...</p> </section> </div>
第二步:用CSS实现卷帘的滚动驱动动画
我们把卷帘层固定在视口,用页面滚动来驱动它的滑出动画,同时让内容容器初始固定,完全隔离文档滚动的影响:
* { margin: 0; padding: 0; box-sizing: border-box; } body { /* 初始隐藏body滚动条,避免双重滚动干扰 */ overflow: hidden; } .shutter { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background-color: #f5f5f5; /* 替换成你的Hero背景色 */ z-index: 10; /* 用页面滚动驱动卷帘的滑出动画 */ animation: slideUp linear forwards; animation-timeline: scroll(root block); /* 动画仅在滚动0到1个视口高度的范围内触发 */ animation-range: 0 100vh; /* 可选:让Hero内容居中显示 */ padding: 2rem; display: flex; flex-direction: column; justify-content: center; align-items: center; } .page-content { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; overflow: hidden; /* 初始隐藏内容,避免卷帘滑出前提前显示 */ visibility: hidden; } .content-block { padding: 2rem; min-height: 100vh; } /* 卷帘向上滑出的关键帧动画 */ @keyframes slideUp { to { transform: translateY(-100%); /* 可选:滑出时添加渐隐效果 */ opacity: 0; } }
第三步:用JS控制内容容器的状态切换
光靠CSS还没法自动释放内容的滚动权限,我们需要在卷帘完全滑出视口后,手动切换内容容器的定位方式:
const shutter = document.querySelector('.shutter'); const pageContent = document.querySelector('.page-content'); const viewportHeight = window.innerHeight; // 页面加载完成后显示内容容器(避免布局跳动) window.addEventListener('load', () => { pageContent.style.visibility = 'visible'; }); window.addEventListener('scroll', () => { const scrollDistance = window.scrollY; // 当滚动距离达到或超过视口高度,说明卷帘已完全滑出 if (scrollDistance >= viewportHeight) { // 让内容容器回到正常文档流,允许正常滚动 pageContent.style.position = 'static'; pageContent.style.height = 'auto'; pageContent.style.overflow = 'visible'; // 恢复body的滚动权限,同时重置滚动位置避免内容跳变 document.body.style.overflow = 'auto'; window.scrollTo(0, 0); // 移除滚动监听,避免重复触发逻辑 window.removeEventListener('scroll', arguments.callee); } });
为什么这个方案能解决你的问题?
你之前的实现中,文档的滚动条同时作用于hero和下方内容——哪怕hero是绝对定位,文档本身的滚动还是会带动内容向上移动。而我们的方案:
- 初始时把内容容器固定在视口,完全隔离文档滚动的影响
- 用滚动时间线把卷帘的滑出和页面滚动绑定,滚动操作只控制卷帘的位移
- 等卷帘彻底消失后,再把内容容器恢复到正常文档流,让页面可以正常滚动
额外优化建议
- 把动画的
linear换成cubic-bezier(0.4, 0, 0.2, 1),让卷帘滑出的动效更自然顺滑 - 如果需要兼容不支持
animation-timeline的旧浏览器,可以把CSS动画换成JS驱动:在scroll事件中计算scrollDistance / viewportHeight的比例,动态设置卷帘的transform: translateY(-${percentage}%)
内容来源于stack exchange
相关产品推荐
相关产品推荐

