如何实现CSS文本动画仅在元素进入视口可见时触发播放
滚动触发CSS动画实现方案
核心逻辑
默认不绑定动画规则,仅当目标元素进入浏览器视口、对用户可见时,才动态添加动画类启动播放,避免页面加载后提前跑完动画。
第一步:修改原有CSS
问题代码说明
原规则直接给文本层绑定动画,页面加载完成后就会自动执行,和元素是否在视口无关。
调整后CSS
保留元素初始隐藏位置,仅在新增的animate类存在时才加载动画规则:
/* 保留文本层初始定位状态 */ .animated-title > div.text-top div { bottom: 0; transform: translate(0, 100%); } .animated-title > div.text-bottom div { top: 0; transform: translate(0, -100%); } /* 新增触发类规则:添加animate类时才启动动画 */ .animated-title.animate > div.text-top div { animation: showTopText 1s; animation-delay: 7s; animation-fill-mode: forwards; } .animated-title.animate > div.text-bottom div { animation: showBottomText 1s; animation-delay: 5s; animation-fill-mode: forwards; }
第二步:新增视口检测JS逻辑
使用原生Intersection Observer API检测元素可见状态,无第三方依赖,滚动性能更优:
// 获取动画目标元素 const animatedTarget = document.getElementById('anime'); // 初始化观察器:元素露出10%即触发,仅执行一次 const viewportObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // 进入视口后添加触发类,启动动画 animatedTarget.classList.add('animate'); // 停止观察,避免重复触发 viewportObserver.unobserve(animatedTarget); } }); }, { threshold: 0.1 // 可调整触发阈值:0.2表示元素露出20%才触发 }); // 启动观察目标元素 viewportObserver.observe(animatedTarget);
补充调整说明
- 原CSS中设置的
animation-delay为元素进入视口后的等待时长,如需元素一进入视口就立刻播放,直接删除两个动画规则中的animation-delay属性即可。 - 请确认原有
@keyframes showTopText规则完整,补充缺失的开头声明:
@keyframes showTopText { 0% { transform: translate3d(0, 100%, 0); } 40%, 60% { transform: translate3d(0, 50%, 0); } 100% { transform: translate3d(0, 0, 0); } }
- 若需要用户滚动离开后再返回时重复播放动画,删除代码中
viewportObserver.unobserve(animatedTarget)一行,可根据需求调整动画填充模式。
内容的提问来源于stack exchange,提问作者Sunnymoon sultan
相关产品推荐
相关产品推荐

