滾動(dòng)條驅(qū)動(dòng)的動(dòng)畫(huà)是一個(gè)新的 CSS 特性,已經(jīng)在部分現(xiàn)代瀏覽器中實(shí)現(xiàn)了,我們以前要實(shí)現(xiàn)滾動(dòng)條動(dòng)畫(huà)效果時(shí),可以使用一些 Javascript 庫(kù)來(lái)實(shí)現(xiàn),例如 ScrollMagic ,Gsap 等動(dòng)畫(huà)庫(kù),現(xiàn)在 CSS 也可以實(shí)現(xiàn)一些基本的滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà)功能了。
我們先來(lái)看看一個(gè)簡(jiǎn)單的 CSS 滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà)的例子。
@keyframes appear {
from {
opacity: 0;
scale: 0.8;
}
to {
opacity: 1;
scale: 1;
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0% cover 50%;
}
animation-timeline 意思是在 img 元素出現(xiàn)在視圖的時(shí)候觸發(fā)。
animation-range 意思是動(dòng)畫(huà)在 img 元素進(jìn)入視口的 0% 時(shí)開(kāi)始,并在視口顯示 img 元素的 50% 時(shí)完成。
通過(guò)上面例子可以看出,當(dāng)圖片開(kāi)始出現(xiàn)在視圖,圖片開(kāi)始觸發(fā) appear 動(dòng)畫(huà),這時(shí)候樣式是 opacity: 0; scale: 0.8 ,隨著向下滾動(dòng),圖片的樣式會(huì)變成 opacity: 1; scale: 1 。
animation-timeline
animation-timeline 用來(lái)實(shí)現(xiàn)滾動(dòng)條動(dòng)畫(huà)時(shí)間軸的來(lái)源,語(yǔ)法如下:
animation-timeline: <timeline-name>;
timeline-name 的枚舉值有:
none:動(dòng)畫(huà)沒(méi)有關(guān)聯(lián)到任何時(shí)間線。 auto :動(dòng)畫(huà)關(guān)聯(lián)到文檔的默認(rèn)時(shí)間線(DocumentTimeline)。默認(rèn)情況下,時(shí)間線是與頁(yè)面加載的時(shí)間相關(guān)聯(lián)的。 scroll() :動(dòng)畫(huà)時(shí)間線和滾動(dòng)條關(guān)聯(lián),基于祖先滾動(dòng)容器的滾動(dòng)進(jìn)度來(lái)驅(qū)動(dòng)動(dòng)畫(huà)。 view():動(dòng)畫(huà)時(shí)間線和當(dāng)前元素的可見(jiàn)性(視口中的位置)相關(guān)聯(lián)。上面介紹了 view() 的用法,接下來(lái)介紹下 scroll() 的用法,直接上代碼:
.scroll-container {
width: 400px;
height: 400px;
overflow: auto;
border: 2px solid #000;
position: relative;
}
.horizontal div {
width: 800px;
height: 100%;
background: linear-gradient(to right, #f06, #4a90e2);
}
.horizontal img {
position: absolute;
width: 200px;
height: 200px;
left: 50%;
display: block;
border: 2px solid #000;
transform-origin: center;
animation: horizontalRotate 1s linear;
animation-timeline: scroll(x);
}
@keyframes horizontalRotate {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
這里定義了一個(gè)容器元素 scroll-container,div 元素是個(gè)配角,主要使容器可以橫向滾動(dòng),我們重點(diǎn)關(guān)注 img 元素,這里設(shè)置了 animation-timeline: scroll(x) 使其可以響應(yīng)父元素的橫向滾動(dòng)來(lái)執(zhí)行動(dòng)畫(huà)效果。
注意這里的容器元素必須要設(shè)置 position: relative ,img 元素才可以找到根據(jù)父元素滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà)。 scroll() 不設(shè)置則默認(rèn)響應(yīng)縱向滾動(dòng)條的滾動(dòng)效果。
最終效果可以自己在 Codepen 查看:
瀏覽器支持情況
截至 2024 年 12 月,瀏覽器的支持情況如下,暫時(shí)還不可以應(yīng)用到生產(chǎn)環(huán)境中。
我們可以使用 @supports 規(guī)則來(lái)檢測(cè)瀏覽器的支持情況來(lái)寫(xiě) animation-timeline 語(yǔ)法,語(yǔ)法如下:
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
/* 編寫(xiě)驅(qū)動(dòng)動(dòng)畫(huà) */
}
}
總的來(lái)說(shuō),能使用 CSS 實(shí)現(xiàn)滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà),對(duì)代碼的實(shí)現(xiàn)以及性能都有很大的好處。未來(lái)瀏覽器會(huì)支持更多的新特性來(lái)實(shí)現(xiàn)復(fù)雜的滾動(dòng)驅(qū)動(dòng)動(dòng)畫(huà),例如 scroll-start-target 等。