CSS - 轉場

轉場 - transition

轉場指的是從一個初始狀態到另一個結束狀態,兩種狀態樣式轉變補間的過程。它通常發生於與使用者的互動,但也有可能是程式改變了 class、ID 或使用了其他狀態。當觸發條件發生,瀏覽器會套用轉場效果,在兩種樣式間漸進發生。最好的例子就是 :hover 偽類,也就是當滑鼠移到元素時所發生的狀態改變。無論轉場或動畫的使用,關係到與使用者的互動感受,因此 duration 時間拿捏非常重要。

以下是當滑鼠移到盒子上時,可以讓背景顏色延遲 1 秒由灰色慢慢變成黃色持續 1 秒的轉場範例:

/* 轉場 bakcground-color 的縮寫 */
.box {
width: 200px;
height: 200px;
background-color: gray;
transition: background-color 1s ease 1s;
}
.box:hover {
background-color: yellow;
}

轉場屬性

轉場可以設定四個屬性值,分別為 transition-property(轉場指定 CSS 屬性)、transition-duration(轉場持續時間)、transition-timing-function(轉場速率)以及  transition-delay(轉場延遲時間),我們可以個別設定轉場屬性,將先前範例縮寫改成個別屬性如下所示:

.box {
width: 200px;
height: 200px;
background-color: gray;
/* 適用所有元素以及偽元素::before、::after */
transition-property: background-color;
transition-duration: 1s;
transition-timing-function: ease;
transition-delay: 1s;
}
.box:hover {
background-color: yellow;
}

重要規則

  • 轉場個別屬性若要設定多屬性值,要以逗號來區隔,代表每個屬性轉場持續時間、轉場速率、延遲時間都不相同。
  • 沒有轉場效果或停用可設定 transition-property:none,或將持續與延遲時間設定為 0s,轉場沒有發生作用一樣。
  • 可以用 all 來指定全部 css 可支援 transition 的屬性效果,但預設已經是 all。
  • border-style 不具備轉場效果。
.box {
/* 逗號隔開屬性,分別對應了各自屬性、持續時間、轉場速率、延遲時間 */
transition-property: color, border, border-radius, transform, opacity;
transition-duration: 1s, 2s, 3s, 4s, 5s;
transition-timing-function: ease, ease-in, ease-out, linear, ease;
transition-delay: 1s, 2s, 3s, 4s, 5s;

/* 沒有轉場效果 */
transition-property: none;
}
  • 當 transform-property 少於持續時間的個數,會忽略多出來的持續時間。
  • 當 transform-property 多於持續時間的個數,則會以流水號重複去分配持續時間,例如 2 個,則會 1,2,1,2,1,2 去分配。
.box {
/* color、border-radius、opacity、width 會被分配到 1 秒 */
/* border、transform、box-shadow、padding 會被分配到 2 秒 */
transition-property: color, border, border-radius, transform, opacity, box-shadow, width, padding;
transition-duration: 1s, 2s;
}

轉場速率

轉場速率動畫速率都是相同的設定,除了分為 ease、ease-in、ease-out、ease-in-out、linear 五個基礎可以設定的數值外,還有 cubic-bezier() 函式與 step-start、step-end、steps(n,start)、steps(n,end) 四種步進函式的設定。

.box {
width: 200px;
height: 200px;
background-color: gray;
transition: background-color 1s 1s;
/* 五種基礎速率函式 */
/* ease(預設)、ease-in、ease-out、ease-in-out、linear */
transition-timing-function: ease;

/* cubic-bezier() 函式 */
transition-timing-function: cubic-bezier(0.12, 0, 0.39, 0);

/* 步進函式 */
/* step-start 等於 steps(1,start) */
transition-timing-function: step-start;
/* step-end 等於 steps(1,end) */
transition-timing-function: step-end;
/* steps(5,start) 第一步動畫開始就步近 */
transition-timing-function: steps(5, start);
/* steps(5,end) 延遲一步動畫才開始步近 */
transition-timing-function: steps(5, end);
}
.box:hover {
background-color: yellow;
}

速率函式

更多 cubic-bezier 函式可參考:

easings
matthewlein

非官方名稱 三次貝茲速率函式
easeInSine cubic-bezier(0.47,0,0.745,0.715)
easeOutSine cubic-bezier(0.39,0.575,0.565,1)
easeInOutSine cubic-bezier(0.445,0.05,0.55,0.95)
easeInQuad cubic-bezier(0.55,0.085,0.68,0.53)
easeOutQuad cubic-bezier(0.25,0.46,0.45,0.94)
easeInOutQuad cubic-bezier(0.455,0.03,0.515,0.955)
easeInCubic cubic-bezier(0.55,0.055,0.675,0.19)
easeOutCubic cubic-bezier(0.215,0.61,0.355,1)
easeInOutCubic cubic-bezier(0.645,0.045,0.355,1)
easeInQuart cubic-bezier(0.895,0.03,0.685,0.22)
easeOutQuart cubic-bezier(0.165,0.84,0.44,1)
easeInOutQuart cubic-bezier(0.77,0,0.175,1)
easeInQuint cubic-bezier(0.755,0.05,0.855,0.06)
easeOutQuint cubic-bezier(0.23,1,0.32,1)
easeInOutQuint cubic-bezier(0.86,0,0.07,1)
easeInExpo cubic-bezier(0.95,0.05,0.795,0.035)
easeOutExpo cubic-bezier(0.19,1,0.22,1)
easeInOutExpo cubic-bezier(1,0,0,1)
easeInCirc cubic-bezier(0.6,0.04,0.98,0.335)
easeOutCirc cubic-bezier(0.075,0.82,0.165,1)
easeInOutCirc cubic-bezier(0.785,0.135,0.15,0.86)
easeInBack cubic-bezier(0.6,-0.28,0.735,0.045)
easeOutBack cubic-bezier(0.175,0.885,0.32,1.275)
easeInOutBack cubic-bezier(0.68,-0.55,0.265,1.55)

負值延遲時間

transition-delay 如果為負數時,會與 transition-duration 相減,得到新的轉場時間。

div {
/* 轉場會變成 持續時間只有 1s,如果transition-delay -2s,那麼轉場持續時間會是 0,不會有持續時間的效果 */
transition-duration: 2s;
transition-delay: -1s;
}

轉場與回場

若將轉場屬性設定在初始狀態,那麼具有轉場回場雙重效果,但若將轉場屬性設定在觸發狀態,那麼只會有轉場效果,而不會有回場效果。例如將 transition-delay 設定在觸發狀態,此時延遲時間只有轉場效果,回場時就沒有延遲時間。

.box {
width: 200px;
height: 200px;
background-color: gray;
transition: 0.2s background-color linear;
}
.box:hover {
background-color: orange;
transition-delay: 1s;
}