<!-- HTML 程式碼 -->
垂直方向改變動畫進度
<div class="out a">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
垂直方向改變動畫進度 ( 限制上 50px 下 100px )
<div class="out b">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
水平方向改變動畫進度
<div class="out c">
<div>往右拉,觀察變化狀況</div><div class="in"></div><div></div>
水平方向改變動畫進度 ( 限制左 50px 右 100px )
<div class="out d">
<div>往右拉,觀察變化狀況</div><div class="in"></div><div></div>
<!-- CSS 程式碼 -->
<style>
.out {
width: 300px;
height: 200px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
margin: 5px 0 20px 0 ;
border: 1px solid #000;
/* 使用一般的 div 撐高畫面,並用漸層背景讓效果更明顯 */
div:not([class]) {
width: 400px;
height: 300px;
background: repeating-linear-gradient(45deg,#fff 0%, #fff 5%,#eee 5%, #eee 10%);
/* 水平捲動的一般 div 高度較小,讓變化的 div 一開始就出現 */
.c div:not([class]), .d div:not([class]) {height: 100px;}
/* 動畫進度會改變的 div,注意只使用了動畫名稱而已 */
.in {
width: 100px;
height: 100px;
background: red;
animation-name: oxxo; /* 只使用動畫名稱 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
25% {background: yellow;}
50% {background: green;}
75% {background: blue;}
100% {
background: black;
width: 20px;
height: 20px;
.a .in {animation-timeline: view();} /* 元素在顯示畫面中垂直方向的位置,等同 view(0% 0%) */
.b .in {animation-timeline: view(50px 100px);} /* 元素在顯示畫面中垂直方向的位置 */
.c .in {
margin: 0 300px; /* 讓畫面出現水平捲軸 */
animation-timeline: view(inline); /* 元素在顯示畫面中水平方向的位置,等同 view(inline 0% 0%) */
.d .in {
margin: 0 300px; /* 讓畫面出現水平捲軸 */
animation-timeline: view(inline 50px 100px ); /* 元素在顯示畫面中水平方向的位置 */
</style>
下方的範例會展示使用 scroll()
屬性值,搭配各種不同參數所呈現的效果,第一組元素會在捲動最靠近元素的父層元素捲軸時發生變化,第二組則是會在捲動頁面捲軸時發生變化,第三組會在捲動元素本身捲軸時發生變化。
線上展示:https://codepen.io/oxxo/pen/gbOaXJo
<!-- HTML 程式碼 -->
最靠近元素的父層元素捲軸
<div class="out a">
<div>往下拉,觀察變化狀況</div>
<div class="in">apple<br>banana<br>oxxo<br>coconut<br>papaya</div>
<div></div>
網頁文件捲軸
<div class="out b">
<div>往下拉,觀察變化狀況</div>
<div class="in">apple<br>banana<br>oxxo<br>coconut<br>papaya</div>
<div></div>
元素本身捲軸
<div class="out c">
<div>往右拉,觀察變化狀況</div>
<div class="in">apple<br>banana<br>oxxo<br>coconut<br>papaya</div>
<div></div>
<br><br><br><br><br><br><br><br><br><br><br><br>
<!-- CSS 程式碼 -->
<style>
.out {
width: 300px;
height: 150px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
margin: 5px 0 20px 0 ;
border: 1px solid #000;
/* 使用一般的 div 撐高畫面,並用漸層背景讓效果更明顯 */
div:not([class]) {
background: repeating-linear-gradient(45deg,#fff 0%, #fff 5%,#eee 5%, #eee 10%);
width: 400px;
height: 50px;
/* 撐高產生捲軸 */
div:nth-child(3){height: 150px;}
/* 動畫進度會改變的 div,注意只使用了動畫名稱而已 */
.in {
width: 100px;
height: 100px;
animation-name: oxxo; /* 動畫名稱 */
overflow: scroll; /* 元素本身產生捲軸 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
25% {background: yellow;}
50% {background: green;}
75% {background: blue;}
100% {
background: black;
width: 20px;
height: 20px;
.a .in {animation-timeline: scroll();} /* 捲動最靠近元素的父層元素捲軸 */
.b .in {animation-timeline: scroll(root);} /* 捲動頁面捲軸 */
.c .in {animation-timeline: scroll(self);} /* 捲動元素本身捲軸 */
</style>
view-timeline 可視範圍時間軸
view-timeline
是針對 animation-timeline
屬性值為 view()
的延伸樣式屬性,可以設定一組類似 CSS 變數的名稱與數值,接著只要呼叫這個名稱,就能執行和 view()
完全相同的效果,這個樣式是 view-timeline-name
、view-timeline-axis
和 view-inset
的縮寫格式,這些樣式屬性都沒有繼承特性,通常只使用 view-timeline
或單純透過 view()
來實現效果。
下方範例會將 animation-timeline: view()
的寫法換成 view-timeline
,會呈現完全相同的效果,當元素離底部 100px 時就會開始變色變小,值到離頂部 50px 為止。
線上展示:https://codepen.io/oxxo/pen/WbNQXBa
<!-- HTML 程式碼 -->
animation-timeline: view(50px 100px);
<div class="out a">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
view-timeline: --a 50px 100px;<br>
animation-timeline: --a;
<div class="out b">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
<!-- CSS 程式碼 -->
<style>
.out {
width: 300px;
height: 200px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
margin: 5px 0 20px 0 ;
border: 1px solid #000;
/* 使用一般的 div 撐高畫面,並用漸層背景讓效果更明顯 */
div:not([class]) {
width: 400px;
height: 300px;
background: repeating-linear-gradient(45deg,#fff 0%, #fff 5%,#eee 5%, #eee 10%);
/* 動畫進度會改變的 div,注意只使用了動畫名稱而已 */
.in {
width: 100px;
height: 100px;
background: red;
animation-name: oxxo; /* 只使用動畫名稱 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
100% {
background: black;
width: 20px;
height: 20px;
.a .in {
view-timeline: --a 50px 100px; /* 建立名稱和數值 */
animation-timeline: --a; /* 讀取名稱 */
.b .in {animation-timeline: view(50px 100px);}
</style>
animation-range 動畫執行範圍
animation-range
表示「動畫執行範圍」的樣式屬性,可以針對 view()
或 scroll()
進行數值範圍設定,這個樣式是 animation-range-start
和 animation-range-end
的縮寫格式,這些樣式屬性都沒有繼承特性,通常只使用 animation-range
來實現效果。
特別注意 animation-range
使用的數值和 view()
與 scroll()
不同,animation-range
的數值表示「元素頂部距離出現位置的距離」。
下方會使用 animation-range
代替 view()
的設定,做出更容易理解位置的效果,和下方的另外一組對照組,呈現完全相同的效果。
線上展示:https://codepen.io/oxxo/pen/zxYvPVG
<!-- HTML 程式碼 -->
animation-timeline: view();<br>
animation-range: 50px 150px;
<div class="out a">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
animation-timeline: view(50px 50px);
<div class="out b">
<div>往下拉,觀察變化狀況</div><div class="in"></div><div></div>
<!-- CSS 程式碼 -->
<style>
.out {
width: 300px;
height: 200px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
margin: 5px 0 20px 0 ;
border: 1px solid #000;
/* 使用一般的 div 撐高畫面,並用漸層背景讓效果更明顯 */
div:not([class]) {
width: 400px;
height: 300px;
background: repeating-linear-gradient(45deg,#fff 0%, #fff 5%,#eee 5%, #eee 10%);
/* 動畫進度會改變的 div,注意只使用了動畫名稱而已 */
.in {
width: 100px;
height: 100px;
background: red;
animation-name: oxxo; /* 只使用動畫名稱 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
100% {
background: black;
width: 20px;
height: 20px;
.a .in {
animation-timeline: view(); /* 使用可視範圍控制動畫進度 */
animation-range: 50px 150px; /* 元素頂部為 50px 開始動畫,值到距離 150px 為止 */
.b .in {
animation-timeline: view(50px 50px); /* 出現時 50px,結束值為 300px-250px */
</style>
對於 view()
而言,animation-range
也可以將上述的數值,搭配下方的屬性值,實現更進階的設定。
normal
預設值,按照上述數值控制元素動畫進度。
contain
元素完全被包含在可視範圍中。
cover
元素在可視範圍進入到完全退出的過程。
元素開始退出可視範圍。
exit-crossing
元素開始穿越可視範圍結束邊緣 ( 類似 exit )。
entry
元素開始進入可視範圍。
entry-crossing
元素開始穿越可視範圍起始邊緣 ( 類似 entry )。
下方會使用六個 div
,從左到右分別是使用 contain
、cover
、exit
、exit-crossing
、entry
和 entry-crossing
所呈現的效果,拖拉捲軸後,可以觀察元素進入和離開可視範圍時動畫進度的表現。
線上展示:https://codepen.io/oxxo/pen/VYwvrJb
<!-- HTML 程式碼 -->
<div class="out">
<div></div>
<div class="in a"></div>
<div class="in b"></div>
<div class="in c"></div>
<div class="in d"></div>
<div class="in e"></div>
<div class="in f"></div>
<div></div>
<!-- CSS 程式碼 -->
<style>
.out {
width: 350px;
height:250px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
margin: 5px 0 20px 0 ;
padding: 20px;
border: 1px solid #000;
background: repeating-linear-gradient(45deg,#fff 0, #fff 25px,#eee 25px, #eee 50px);
background-attachment: local;
/* 使用一般的 div 撐高畫面,並用漸層背景讓效果更明顯 */
div:not([class]) {
width: 400px;
height: 300px;
clear: both;
/* 動畫進度會改變的 div,注意只使用了動畫名稱而已 */
.in {
width: 40px;
height: 100px;
margin: 5px;
float: left;
background: red;
animation-name: oxxo; /* 動畫名稱 */
animation-fill-mode: forwards; /* 動畫結束後停留在最後一格 */
animation-timeline: view(); /* 使用可視範圍控制動畫進度 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
100% {
background: black;
height: 200px;
.a {animation-range: contain;}
.b {animation-range: cover;}
.c {animation-range: exit;}
.d {animation-range: exit-crossing;}
.e {animation-range: entry;}
.f {animation-range: entry-crossing;}
</style>
因為 animation-scroll
無法讀取捲軸移動距離,而透過 animation-range
就能讀取捲軸捲動的數值,透過下拉捲軸的距離控制動畫進度,下方範例會將三個 div
套用不同的 animation-range
,執行後將捲軸向下拉動,可以發現三個 div
會在不同高度捲軸時開始執行動畫進度,產生有趣的視覺效果。
線上展示:https://codepen.io/oxxo/pen/jEObajd
<!-- HTML 程式碼 -->
<div class="out">
<div class="in a"></div>
<div class="in b"></div>
<div class="in c"></div>
<div></div>
<!-- CSS 程式碼 -->
<style>
.out {
width: 350px;
height:250px;
overflow: scroll; /* 隱藏超出範圍的子元素並出現捲軸 */
padding: 20px;
border: 1px solid #000;
background: repeating-linear-gradient(45deg,#fff 0, #fff 25px,#eee 25px, #eee 50px); /* 用漸層背景讓效果更明顯 */
background-attachment: local; /* 固定背景 */
div:not([class]) {
width: 400px;
height: 1000px;
clear: both;
.in {
width: 100px;
height: 100px;
margin: 5px;
float: left;
background: red;
animation-name: oxxo; /* 動畫名稱 */
animation-fill-mode: forwards; /* 動畫結束後停留在最後一格 */
animation-timeline: scroll(); /* 根據捲軸播放動畫進度 */
/* 動畫設定 */
@keyframes oxxo {
0% {background: red;}
100% {
background: black;
height: 300px;
.a {animation-range: 10px 100px;} /* 動畫範圍是捲軸移動的 10px~100px */
.b {animation-range: 50px 150px;} /* 動畫範圍是捲軸移動的 50px~150px */
.c {animation-range: 100px 200px;} /* 動畫範圍是捲軸移動的 100px~200px */
</style>
一但可以透過元素在「可視範圍的位置」或「捲軸位置」控制動畫進度,就更能大幅發揮 CSS 強大的動畫能力,甚至不需要 JavaScript 就能做出許多有趣的捲軸效果,可惜目前還有部分瀏覽器不支援,不過相信這種好用的功能,不久的未來應該會都支援囉。
延伸閱讀:
CSS 動畫 animation
純 CSS 視差滾動效果
如果有任何建議或問題,可傳送「」給我,謝謝~