CSS view():以后做滚动动画不用写JS了
以前做滚动动画,一看代码里有scroll监听、getBoundingClientRect()、节流、防抖,还要自己算进度条,我就知道后面要麻烦了。
不是说不能写。是这种代码一多,动画、性能、后面好不好改,这三样经常都保不住。浏览器明明自己就知道元素有没有进到视野里、滚动到哪了,结果我们非要用JavaScript再算一遍。
现在这事,CSS已经接过去一大块了。滚动动画可以直接跟滚动条走,view()就是里面最好用的一个。它会根据元素在滚动容器里的可见程度来推动动画。
以前要写一大堆代码
很多人以前是这么写的:
const cards = document.querySelectorAll('.card')
function update() {
const vh = window.innerHeight
cards.forEach((card) => {
const rect = card.getBoundingClientRect()
const start = vh * 0.9
const end = vh * 0.2
const progress = Math.min(
1,
Math.max(0, (start - rect.top) / (start - end))
)
card.style.opacity = progress
card.style.transform = `translateY(${(1 - progress) * 40}px)`
})
}
window.addEventListener('scroll', update, { passive: true })
window.addEventListener('resize', update)
update()这段代码不是随便写的例子,很多线上项目真就这么干的。问题也很明显:
第一,你得自己算“什么时候开始进场、什么时候算结束”。
第二,页面一复杂,滚动的不止是整个页面,还有里面的小区域,判断就开始乱。
第三,动画逻辑全散在JS里,样式和行为搅在一起,后面谁接手谁头疼。
用view()怎么写
换成view(),思路就清爽多了:
.card {
opacity: 0;
transform: translateY(40px);
animation: card-in both linear;
animation-timeline: view();
animation-range: entry 20% cover 40%;
}
@keyframes card-in {
to {
opacity: 1;
transform: translateY(0);
}
}<section class="card">订单服务</section>
<section class="card">库存服务</section>
<section class="card">通知服务</section>这里没写一行滚动计算的代码。元素滚进视野,动画自己动;往回滚,动画也跟着倒回去。这个机制说白了就是“动画走到哪跟滚动条走到哪绑在一起”,不像以前那样时间到了自己播完。
view()适合干什么
我自己会拿它做这几类东西:
页面往下翻的时候,卡片一个个淡入
文章里的章节标题、配图、时间线进场
那种“滚到哪一块,哪一块亮起来”的简单效果
这类动画以前最烦人的不是写不出来,是你得一直维护那套“滚动位置转成动画进度”的代码。现在浏览器自己能管,就别自己扛着了。
再来个例子
做一个侧边目录高亮的效果,同样不用碰JS:
.doc-block {
--p: 0;
animation: block-focus both linear;
animation-timeline: view(block);
animation-range: entry 10% cover 30%;
}
@keyframes block-focus {
from {
opacity: .5;
transform: scale(.98);
}
to {
opacity: 1;
transform: scale(1);
}
}这里的view(block)意思是沿着块方向跟踪可见进度。view()可以加轴参数,也能调inset来改“多早算进入视野”。
这东西也有毛病
第一,现在还不是所有浏览器都支持。MDN上标的“Limited availability”,就是说主流浏览器还没全覆盖。真要用在正式项目上,还是得看看你的用户用什么浏览器。
第二,它代替不了所有JavaScript。你要做复杂的联动、跟数据挂钩的动画、滚动和业务状态绑得紧的,JS还是得上。但那种只是“元素滚进来动一下”的需求,再写满屏监听和计算,就有点说不过去了。
说句实在话
更准确的说法不是“JavaScript滚动动画死了”,是很多本来就不该让JS管的滚动动画,终于可以还给CSS了。
前端这几年有些进步我是真喜欢,不是功能变花哨了,是浏览器终于开始接手那些本来就该它干的累活。view()就属于这种。能少写一段滚动监听,就少留一个掉帧的地方。文章页、官网、活动页,用这个东西能省你不少事。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!