CSS animation 動畫
animation 可以建立更複雜的動畫效果,比 transition 更靈活,可以控制關鍵影格、重複次數、方向等。
@keyframes 定義動畫
使用 @keyframes 定義動畫的關鍵影格:
@keyframes 動畫名稱 {
from {
/* 起始狀態 */
}
to {
/* 結束狀態 */
}
}
或使用百分比指定多個關鍵影格:
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
100% {
transform: translateY(0);
}
}
套用動畫
.box {
animation: bounce 1s ease infinite;
}
animation 子屬性
animation-name
指定要使用的動畫名稱。
.box {
animation-name: bounce;
}
animation-duration
動畫持續時間。
.box {
animation-duration: 1s;
animation-duration: 500ms;
}
animation-timing-function
動畫的速度曲線。
.box {
animation-timing-function: ease; /* 預設 */
animation-timing-function: linear;
animation-timing-function: ease-in;
animation-timing-function: ease-out;
animation-timing-function: ease-in-out;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
animation-timing-function: steps(4);
}
animation-delay
動畫開始前的延遲時間。
.box {
animation-delay: 0.5s;
animation-delay: -0.5s; /* 負值會讓動畫從中間開始 */
}
animation-iteration-count
動畫重複次數。
.box {
animation-iteration-count: 1; /* 預設,執行 1 次 */
animation-iteration-count: 3; /* 執行 3 次 */
animation-iteration-count: infinite; /* 無限重複 */
}
animation-direction
動畫播放方向。
.box {
animation-direction: normal; /* 預設,正向播放 */
animation-direction: reverse; /* 反向播放 */
animation-direction: alternate; /* 正向、反向交替 */
animation-direction: alternate-reverse; /* 反向、正向交替 */
}
animation-fill-mode
動畫結束後的狀態。
.box {
animation-fill-mode: none; /* 預設,回到初始狀態 */
animation-fill-mode: forwards; /* 保持在最後一個影格 */
animation-fill-mode: backwards; /* 在延遲期間套用第一個影格 */
animation-fill-mode: both; /* 同時套用 forwards 和 backwards */
}
animation-play-state
控制動畫播放或暫停。
.box {
animation-play-state: running; /* 播放(預設) */
animation-play-state: paused; /* 暫停 */
}
/* 常用於 hover 暫停動畫 */
.box:hover {
animation-play-state: paused;
}
animation 縮寫
/* animation: name duration timing-function delay iteration-count direction fill-mode; */
.box {
animation: bounce 1s ease 0s infinite alternate forwards;
}
/* 簡化 */
.box {
animation: bounce 1s infinite;
}
多個動畫
用逗號分隔套用多個動畫:
.box {
animation:
bounce 1s ease infinite,
fade 2s ease-in-out infinite alternate;
}
實用範例
淡入
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fade-in {
animation: fadeIn 0.5s ease forwards;
}
從下滑入
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.slide-up {
animation: slideUp 0.5s ease forwards;
}
脈動效果
@keyframes pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
}
.pulse {
animation: pulse 2s ease-in-out infinite;
}
旋轉載入
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spinner {
animation: spin 1s linear infinite;
}
彈跳效果
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-15px);
}
}
.bounce {
animation: bounce 0.6s ease infinite;
}
搖晃效果
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
75% {
transform: translateX(5px);
}
}
.shake {
animation: shake 0.5s ease;
}
閃爍效果
@keyframes blink {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
.blink {
animation: blink 1s step-end infinite;
}
打字效果
@keyframes typing {
from {
width: 0;
}
to {
width: 100%;
}
}
@keyframes cursor {
50% {
border-color: transparent;
}
}
.typewriter {
overflow: hidden;
white-space: nowrap;
border-right: 2px solid black;
animation:
typing 3s steps(30) forwards,
cursor 0.5s step-end infinite;
}
交錯動畫
.item {
animation: fadeIn 0.5s ease forwards;
opacity: 0;
}
.item:nth-child(1) { animation-delay: 0.1s; }
.item:nth-child(2) { animation-delay: 0.2s; }
.item:nth-child(3) { animation-delay: 0.3s; }
.item:nth-child(4) { animation-delay: 0.4s; }
效能建議
- 優先動畫
transform和opacity - 避免動畫會觸發重排的屬性(width、height、margin 等)
- 使用
will-change提示瀏覽器優化
.animated {
will-change: transform, opacity;
}
尊重使用者偏好
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}