轉場 transition
CSS 的轉場 transition 可以讓元素在樣式屬性值改變的時候,產生「過程的變化」,進而展現更平滑順暢的漸變效果,這篇教學會介紹 CSS 轉場的相關屬性 transition-property、transition-duration、transition-delay、transition-behavior 和 transition-timing-function,也會介紹透過 CSS 函式 cubic-bezier 創造特別的轉場速度變化。
快速導覽:
transition-duration 轉場持續時間
transition-duration
表示「轉場持續時間」的樣式屬性,預設值 0 表示不轉場,沒有繼承特性,使用非負值的數值,數值需要搭配「s」( 秒 ) 或「ms」( 1/1000 秒、毫秒 ) 等時間單位,只要轉場時間不為 0,瀏覽器就會在樣式屬性的「開始」的屬性值與「結束」屬性值之間,自動計算補間動畫數值。
注意,能夠加入補間動畫數值的樣式屬性,需要具備能「計算」的屬性值,例如顏色、位置、尺寸、角度、透明度...等,如果是使用「關鍵字」作為屬性值,則無法加入補間動畫效果,例如
none
、solid
、dashed
...等。
下方範例使用四個 h2
元素,前三個 h2
當滑鼠移動到文字上方時分別會產生 0.75 秒和 0.3 秒的轉場效果,而第四個 h2
因為是在 solid
和 dashed
之間切換,就不會有轉場效果。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">我會變大</h2>
<h2 class="b">我會變色</h2>
<h2 class="c">我會變透明</h2>
<h2 class="d">我無法產生補間動畫</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
border: 3px solid #000;
width: 240px;
height: 50px;
}
.a {transition-duration: .75s;} /* 轉場持續時間 0.75 秒 */
.a:hover {font-size: 30px;}
.b {transition-duration: 750ms;} /* 轉場持續時間 0.75 秒 */
.b:hover {
color: red;
border-color: red;
}
.c {transition-duration: 0.3s;} /* 轉場持續時間 0.3 秒 */
.c:hover {opacity: 0;}
.d {transition-duration: 0.3s;} /* 轉場持續時間 0.75 秒 */
.d:hover {
border-style: dashed; /* 這種關鍵字屬性值無法產生補間動畫的轉場效果 */
}
</style>
轉場持續時間作用在「目前的選擇器」,因此同一個元素可以透過不同的選擇器,套用不同的持續時間,下方範例的 h2
在滑鼠移動到上方時,會使用 3 秒的轉場持續時間,當滑鼠離開後,會改用 0.5 秒的轉場持續時間。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2>oxxo</h2>
<!-- CSS 程式碼 -->
<style>
h2 {transition-duration: 0.5s;}
h2:hover {
transition-duration: 3s;
font-size: 40px;
}
</style>
transition-property 轉場屬性
transition-property
表示「要套用轉場的樣式屬性」,預設值「all」表示全部能套用轉場的樣式屬性都會套用,沒有繼承特性,也可以直接將特定樣式屬性名稱作為屬性值,若有多個樣式屬性則使用「逗號」分隔。
注意,能夠加入補間動畫數值的樣式屬性,需要具備能「計算」的屬性值,例如顏色、位置、尺寸、角度、透明度...等,如果是使用「關鍵字」作為屬性值,則無法加入補間動畫效果,例如
none
、solid
、dashed
...等。
下方範例有兩個 h2
,第一個 h2
所有樣式都會套用轉場效果,而第二個 h2
只有顏色和透明度會套用轉場效果 ( 所以會有「直接變大」的感覺 )。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">所有樣式都會有轉場效果</h2>
<h2 class="b">只有顏色、透明度有轉場效果</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
transition-duration: 1s;
border: 2px solid #000;
}
h2:hover {
color: red;
font-size:30px;
opacity: 0.2;
border-width: 5px;
}
.a {transition-property: all;}
.b {transition-property: color, opacity;} /* 只有 color 和 opacity 要套用轉場效果 */
</style>
如果使用 transition-property
設定「多組」樣式屬性,也能搭配 transition-duration
讓多組樣式屬性都使用不同的轉場持續時間,下方的範例會讓 width
、height
、font-size
、border-width
套用不同的轉場時間。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<div>oxxo</div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover+div {
width: 200px;
height: 200px;
font-size: 80px;
border-width: 10px;
}
div {
width: 100px;
height: 100px;
border: 2px solid #000;
transition-property: width, height, font-size, border-width;
transition-duration: 1s, 3s, 5s, 2s; /* 轉場時間分別對應上方樣式屬性 */
}
</style>
transition-delay 轉場延遲時間
transition-delay
表示「延遲多久後進行轉場」,預設值 0 表示不延遲,沒有繼承特性,使用非負值的數值,數值需要搭配「s」( 秒 ) 或「ms」( 1/1000 秒、毫秒 ) 等時間單位。下方範例有兩個 h2
,第一個 h2
不會延遲,而第二個 h2
會套用 1 秒的延遲效果。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">我沒有延遲</h2>
<h2 class="b">我會延遲 1 秒</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
transition-duration: 1s;
border: 2px solid #000;
}
h2:hover {
color: red;
font-size:30px;
opacity: 0.2;
border-width: 5px;
}
.a {transition-delay: 0;}
.b {transition-delay: 1s;} /* 延遲一秒 */
</style>
transition-behavior 轉場行為
transition-behavior
是一個專門針對「離散樣式屬性」設定「轉場行為」的樣式屬性,預設值為 normal,沒有繼承特性。所謂的「離散」樣式屬性就是「不連續」的樣式屬性,泛指為透過「關鍵字」為屬性值的樣式,例如 border-style
使用 solid
、dashed
、dotted
等,或 display
使用 none
、block
等,都屬於「離散」樣式屬性,如果將 transition-behavior
屬性值設定為 allow-discrete
,則可以讓這些無法產生轉場補間動畫效果的樣式屬性,在轉場過程中更加平順。
不論有沒有設定
transition-behavior
,都不會影響非離散的樣式屬性。
下方範例使用兩個 h2
分別呈現 normal
和 allow-discrete
的效果,可以看到雖然 border
的 solid
樣式無法直接轉變成 dashed
,但設定為 allow-discrete
的轉場效果明顯好很多。
<!-- HTML 程式碼-->
將滑鼠移動到下方文字上
<h2 class="a">normal</h2>
<h2 class="b">allow-discrete</h2>
<!-- CSS 程式碼 -->
<style>
h2 {
width: 240px;
height: 100px;
transition-duration: 2s;
border: 20px solid #000;
box-sizing: border-box;
}
h2:hover {border: 1px dashed #000;}
.b {transition-behavior: allow-discrete;}
</style>
不過如果要透過 transition-behavior
設定 display:none
的變化,需要額外搭配 opacity
樣式屬性和額外運用 @starting-style
聲明起始樣式,@starting-style
主要定義元素某個樣式屬性的「起始值」,各自負責的轉場效果如下:
- 從顯示到消失:
transition-behavior: allow-discrete;
- 從消失到顯示:
@starting-style
下方範例當滑鼠移動到第一個紅色 h2
時,會將下方兩個白色 h2
設定為 display:none
,由於第一個 h2
設定了 transition-behavior: allow-discrete;
,會先出現 1 秒的轉場效果再將元素隱藏,最下方的文字也會在上方元素隱藏後,自動位移到上面。
<!-- HTML 程式碼-->
<h2 class="a">將滑鼠移到我上方</h2>
<h2 class="b">allow-discrete ( 轉場消失 )</h2>
<h2 class="c">normal ( 直接消失 )</h2>
oxxo.studio ( 上方元素 display:none 之後會自動上移 )
<!-- CSS 程式碼 -->
<style>
h2 {
width: 320px;
height: 60px;
transition-duration: 1s;
border: 3px solid #000;
background: #fff;
}
.a {background: pink;}
/* 滑鼠移動到 .a 上方,.a 後方所有的 h2 */
.a:hover~h2 {
opacity: 0;
display: none;
}
.b {transition-behavior: allow-discrete;}
@starting-style {
.b {opacity: 0;} /* 避免滑鼠離開後,透明度直接變成 1 */
}
</style>
transition-timing-function 轉場速度
transition-timing-function
可以控制「轉場的速度」,預設值為 ease
,沒有繼承特性,這個樣式屬性可以讓轉場的過程具有「加速、減速、平緩加速、線性移動」等速度變化,根據「W3C CSS Easing Functions Level 1」的說明,共有下列幾種屬性值:
屬性值 | 說明 |
---|---|
linear | 線性,沒有加減速。 |
ease-in | 加速開始,線性停止。 |
ease-out | 線停開始,減速停止。 |
ease-in-out | 加速開始,減速停止。 |
ease | 加速開始,減速停止。 |
step-start | 轉場時間後直接跳到完成樣式。 |
step-end | 直接跳到完成樣式,並等待轉場時間。 |
steps(n, jump-start) | 分成 n 個步驟跳往完成樣式。 |
steps(n, jump-end) | 分成 n 個步驟跳往完成樣式。 |
steps(n, jump-none) | 分成 n-1 個步驟跳往完成樣式。 |
steps(n, jump-both) | 分成 n+1 個步驟跳往完成樣式。 |
下方範例會讓不同的 div
從左移動到右,可以觀察不同轉場速度的效果。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>linear</h3><div></div>
<h3>ease-in</h3><div></div>
<h3>ease-out</h3><div></div>
<h3>ease-in-out</h3><div></div>
<h3>ease</h3><div></div>
<h3>step-start</h3><div></div>
<h3>step-end</h3><div></div>
<h3>steps(5, jump-start)</h3><div></div>
<h3>steps(5, jump-end)</h3><div></div>
<h3>steps(5, jump-none)</h3><div></div>
<h3>steps(5, jump-both)</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
transition-duration: 5s;
}
h3 {
margin:5px;
width: 190px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition-duration: 1s;
}
div:nth-of-type(1) {transition-timing-function: linear;}
div:nth-of-type(2) {transition-timing-function: ease-in;}
div:nth-of-type(3) {transition-timing-function: ease-out;}
div:nth-of-type(4) {transition-timing-function: ease-in-out;}
div:nth-of-type(5) {transition-timing-function: ease;}
div:nth-of-type(6) {transition-timing-function: step-start;}
div:nth-of-type(7) {transition-timing-function: step-end;}
div:nth-of-type(8) {transition-timing-function: steps(5, jump-start);}
div:nth-of-type(9) {transition-timing-function: steps(5, jump-end);}
div:nth-of-type(10) {transition-timing-function: steps(5, jump-none);}
div:nth-of-type(11) {transition-timing-function: steps(5, jump-both);}
</style>
除了使用預設的轉場速度,也可以使用 CSS 內建函式 cubic-bezier
設定「客製化的轉場速度」,cubic-bezier
是一個可調整的「貝茲曲線」,總共有四個參數,分別是第一個貝茲曲線控制點 p1 的座標 (x1, y1) 和第二個貝茲曲線控制點 p2 的座標 (x2, y2) ( 參考 Cubic Bézier )。
透過線上工具「cubic-bezier.com」可以使用視覺化的方式,拖拉這兩個控制點,調整控制點之後,上方就會看見這個轉場速度的寫法。
下方範例會透過 cubic-bezier
,產生四種有趣的轉場速度,從中可以看到當設定值超過範圍時,甚至會產生超過原本邊界的特殊效果。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>cubic-bezier(.24,1.19,.68,-0.07)</h3><div></div>
<h3>cubic-bezier(.96,.34,0,.73)</h3><div></div>
<h3>cubic-bezier(.46,-0.75,.18,1.49)</h3><div></div>
<h3>cubic-bezier(.41,.86,.55,2.08)</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
transition-duration: 5s;
}
h3 {
margin:5px;
width: 290px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition-duration: 1s;
}
div:nth-of-type(1) {transition-timing-function: cubic-bezier(.24,1.19,.68,-0.07);}
div:nth-of-type(2) {transition-timing-function: cubic-bezier(.96,.34,0,.73);}
div:nth-of-type(3) {transition-timing-function: cubic-bezier(.46,-0.75,.18,1.49);}
div:nth-of-type(4) {transition-timing-function: cubic-bezier(.41,.86,.55,2.08);}
</style>
transition 轉場屬性縮寫
元素套用轉場效果時,為了避免 CSS 程式碼過於冗長,通常不會使用個別的轉場樣式屬性,往往會使用縮寫的 transition
樣式屬性,使用 transition
時只需要將個別的轉場樣式寫在後方,除了轉場時間和延遲時間有順序,其他關鍵字排列沒有順序之分,下方所列出的寫法都是合乎規規則的寫法:
div {
transition: 1s; /* 持續時間 1s */
transition: 1s 0.5s; /* 持續時間 1s,延遲時間 0.5s */
transition: 1s ease-in; /* 持續時間 1s,使用 ease-in 轉場速度 */
transition: 1s 0.5s ease-in; /* 持續時間 1s,延遲時間 0.,5s,使用 ease-in 轉場速度 */
transition: 1s color; /* 持續時間 1s,針對 color */
}
下方的範例使用 transition
讓四個 div
用不同的方式進行轉場。
<!-- HTML 程式碼-->
<h2>滑鼠移動到我上方看效果</h2>
<h3>transition: 5s</h3><div></div>
<h3>transition: 5s ease-in-out</h3><div></div>
<h3>transition: 3s 2s margin-left</h3><div></div>
<h3>transition: 3s 2s</h3><div></div>
<!-- CSS 程式碼 -->
<style>
h2 {border: 2px solid #000;}
h2:hover~div {
margin-left: 200px;
background: green;
}
h3 {
margin:5px;
width: 290px;
height: 30px;
float:left;
clear: both;
text-align: right;
}
div {
float:left;
width: 30px;
height: 30px;
margin:5px;
background: red;
transition: 1s;
}
h2:hover~div:nth-of-type(1) {transition: 5s;}
h2:hover~div:nth-of-type(2) {transition: 5s ease-in-out}
h2:hover~div:nth-of-type(3) {transition: 3s 2s margin-left;} /* 只針對 margin-left */
h2:hover~div:nth-of-type(4) {transition: 3s 2s;}
</style>
小結
transition
通常應用於按鈕、選單、或任何需要「動態出現或移動」的元素,透過轉場效果,可以讓元素不會突兀的出現或改變位置,是很常見的樣式屬性。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~