滑动门效果:用CSS实现滚动元素水平移动,替代Intersection Observer
修复CSS滚动驱动动画实现双图反向移动效果
原代码无法正常运行的核心问题如下:
- 滚动驱动动画(view timeline)不能使用固定时间单位的
animation-duration,否则动画会瞬间执行完毕,无法和滚动进度绑定 - 两张图片初始绝对定位完全重叠,没有预先布局成居中并排的状态,移动时无法正确露出背景
- 未明确动画的滚动触发区间,导致动画执行时机不符合预期
修复后的完整代码
HTML
<div class="row riviste-background"> <img src="https://picsum.photos/500/400" alt="" class="riviste" id="riv1"> <img src="https://picsum.photos/500/400" alt="" class="riviste" id="riv2"> </div>
CSS
.riviste-background { background: url('../img/vincitrice.jpg'); background-position: center center; background-size: 50% auto; background-repeat: no-repeat; position: relative; height: calc(150vh - 15vw); overflow: hidden; /* 防止图片移动超出容器 */ } .riviste { width: 500px; height: auto; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* 初始居中基准 */ animation-timeline: view(block); animation-duration: 100%; /* 绑定滚动全程进度 */ animation-fill-mode: both; animation-range: entry 0% cover 100%; /* 动画触发区间:元素进入视口到完全离开 */ } #riv1 { animation-name: slide-left; transform: translate(calc(-50% - 250px), -50%); /* 初始左移半张图宽度,与riv2并排 */ } #riv2 { animation-name: slide-right; transform: translate(calc(-50% + 250px), -50%); /* 初始右移半张图宽度,与riv1并排 */ } @keyframes slide-left { to { transform: translate(calc(-50% - 75%), -50%); /* 滚动时持续左移 */ } } @keyframes slide-right { to { transform: translate(calc(-50% + 75%), -50%); /* 滚动时持续右移 */ } }
关键修改说明
- 容器布局优化:添加
overflow: hidden避免图片移动后超出容器范围,移除不必要的flex布局属性(子元素用绝对定位无需flex控制) - 初始图片定位:通过
translate计算调整两张图片的初始位置,让它们并排覆盖背景图,确保移动过程中能露出中间背景 - 滚动动画参数修正:
animation-duration: 100%:让动画时长完全对应元素在视口中滚动的完整周期animation-range:明确动画触发的滚动区间,保证滚动过程中动画持续播放
- 动画逻辑调整:保留反向移动的核心需求,调整transform的计算方式,确保移动轨迹符合预期
内容的提问来源于stack exchange,提问作者Biyou Scherma
相关产品推荐
相关产品推荐

