如何将hover触发的CSS动画改为页面加载及滚动入视图时触发?
问题描述
当前我的CSS动画仅在hover(悬停)时触发,如何将其改为自动执行?
我曾尝试应用keyframes(关键帧)和animation属性,但动画直接完成,未呈现过渡效果,尽管transition(过渡)属性设置正确。
下方示例中的动画仅在悬停时触发,如何修改使其在页面加载时触发?预期效果是动画在页面加载时触发,且仅当元素滚动到视图范围内时执行。
原代码
CSS
main { padding: 5rem 0; display: flex; align-items: center; justify-content: center; } main .carousel { max-height: 500px; overflow: hidden; } main .carousel figure { height: 500px; background: url("https://res.cloudinary.com/dqjhiewf1/image/upload/v1666092821/fullPagePrint/portfolio_fullpage_kg2c1w.png"); width: 550px; background-size: cover; background-position: top center; transform: perspective(1000px) rotateY(-13deg) rotateX(5deg) rotate(1deg) scaleY(0.9) scaleX(0.95) translate(-3%) translateY(-3%); transition: all 8.5s ease, transform 0.5s ease; } main .carousel figure:hover { background-position: bottom center; cursor: pointer; overflow: auto; transform: perspective(1000px) rotateY(0) rotateX(0) rotate(0) scale(1) translate(0) translateY(0); transition: all 8.5s ease, transform 0.5s ease; }
HTML
<main> <a href="https://axie-infinity-lp.vercel.app" target="_blank"> <div class="carousel"> <figure></figure> </div> </a> </main>
解决方案
要实现元素进入视图时自动执行动画,需要结合CSS关键帧动画和Intersection Observer API,具体修改如下:
1. 定义CSS关键帧动画
把hover状态的变化转换成关键帧,明确动画的起始和结束状态:
@keyframes revealImage { 0% { background-position: top center; transform: perspective(1000px) rotateY(-13deg) rotateX(5deg) rotate(1deg) scaleY(0.9) scaleX(0.95) translate(-3%) translateY(-3%); } 100% { background-position: bottom center; transform: perspective(1000px) rotateY(0) rotateX(0) rotate(0) scale(1) translate(0) translateY(0); } }
2. 修改元素基础样式与动画触发规则
移除hover伪类样式,新增一个animate类用于触发动画,同时保留元素的交互属性:
main .carousel figure { height: 500px; background: url("https://res.cloudinary.com/dqjhiewf1/image/upload/v1666092821/fullPagePrint/portfolio_fullpage_kg2c1w.png"); width: 550px; background-size: cover; background-position: top center; transform: perspective(1000px) rotateY(-13deg) rotateX(5deg) rotate(1deg) scaleY(0.9) scaleX(0.95) translate(-3%) translateY(-3%); cursor: pointer; overflow: auto; } /* 添加动画触发类,forwards 让元素保持动画结束后的状态 */ main .carousel figure.animate { animation: revealImage 8.5s ease forwards; }
3. 用Intersection Observer监听视图进入事件
添加JS代码,当元素滚动到视图范围内时,自动为其添加animate类触发动画:
// 获取目标元素 const targetFigure = document.querySelector('main .carousel figure'); // 创建观察者实例,设置触发条件 const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // 元素进入视图,启动动画 entry.target.classList.add('animate'); // 仅执行一次,停止观察当前元素 observer.unobserve(entry.target); } }); }, { threshold: 0.1 // 元素10%进入视图时触发动画 }); // 开始监听目标元素 observer.observe(targetFigure);
完整修改后代码
CSS
main { padding: 5rem 0; display: flex; align-items: center; justify-content: center; } main .carousel { max-height: 500px; overflow: hidden; } @keyframes revealImage { 0% { background-position: top center; transform: perspective(1000px) rotateY(-13deg) rotateX(5deg) rotate(1deg) scaleY(0.9) scaleX(0.95) translate(-3%) translateY(-3%); } 100% { background-position: bottom center; transform: perspective(1000px) rotateY(0) rotateX(0) rotate(0) scale(1) translate(0) translateY(0); } } main .carousel figure { height: 500px; background: url("https://res.cloudinary.com/dqjhiewf1/image/upload/v1666092821/fullPagePrint/portfolio_fullpage_kg2c1w.png"); width: 550px; background-size: cover; background-position: top center; transform: perspective(1000px) rotateY(-13deg) rotateX(5deg) rotate(1deg) scaleY(0.9) scaleX(0.95) translate(-3%) translateY(-3%); cursor: pointer; overflow: auto; } main .carousel figure.animate { animation: revealImage 8.5s ease forwards; }
HTML
<main> <a href="https://axie-infinity-lp.vercel.app" target="_blank"> <div class="carousel"> <figure></figure> </div> </a> </main>
JavaScript
const targetFigure = document.querySelector('main .carousel figure'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animate'); observer.unobserve(entry.target); } }); }, { threshold: 0.1 }); observer.observe(targetFigure);
说明
- 关键帧动画明确了状态过渡的全过程,
forwards属性确保动画结束后元素保持最终状态。 - Intersection Observer API相比传统滚动事件更高效,
threshold参数可灵活调整动画触发的时机。 - 通过类触发动画的方式,确保动画仅在元素进入视图时执行一次,符合需求。
内容的提问来源于stack exchange,提问作者momola
相关产品推荐
相关产品推荐

