← Back to list

動畫疊加不再怕相互覆蓋!淺談 CSS animation-composition

你有沒有遇過這種情況:元素本來就有 transform: rotate(45deg),滑鼠 hover 的時候想加上一個 translateX 動畫,結果一跑起來,旋轉就消失了?

Jamie li · 2026-03-31 01:44 · 1 claps · 4.8 min read
#animation-composition #css #web-animation #front-end-development
Open on Medium ↗
Wiki topics: VIS · Visual & Graphic Design 🌐 · Web Development 🎬 · Film & Television

動畫疊加不再怕相互覆蓋!淺談 CSS animation-composition

你有沒有遇過這種情況:元素本來就有 transform: rotate(45deg),滑鼠 hover 的時候想加上一個 translateX 動畫,結果一跑起來,旋轉就消失了?

整個動畫只剩 translateX 在跑,rotate 完全不見,於是你就開始幫自己增加工作量,要馬調整 DOM 結構多包一層,要馬就進行手動加總。

但現在你有其他選擇了!那就是 CSS animation-composition!

animation-composition 登場

animation-composition 告訴瀏覽器:當動畫效果和元素本身既有的屬性值相遇時,要怎麼「合併」它們。

共有三個值可以選:

replace(預設)

動畫值直接取代底層值。預設行為,也是 rotate 會消失的原因。

.box {
  transform: rotate(45deg); /* 底層值 */
}

@keyframes slide {
  to { transform: translateX(100px); } /* 動畫值 */
}
/* 結果:rotate(45deg) 不見,只剩 translateX(100px) */

add

動畫值附加在底層值後面,兩者並排存在。

.box {
  transform: rotate(45deg);
}

@keyframes slide {
  to { transform: translateX(100px); }
}
.box:hover {
  animation: slide 0.5s forwards;
  animation-composition: add;
}
/* 結果:rotate(45deg) translateX(100px) */

accumulate

動畫值和底層值數學相加,適用於同類型的值。

.box {
  transform: translateX(30px);
}

@keyframes slide {
  to { transform: translateX(100px); }
}
.box:hover {
  animation: slide 1s forwards;
  animation-composition: accumulate;
}
/* 結果:translateX(130px) */

add vs accumulate 一句話分清楚:

add:scale(1.4) + scale(2.5) → scale(1.4) scale(2.5)(兩個scale 疊加,變成 1.4×2.5 = 3.5 倍)

accumulate:blur(2px) + blur(3px) → blur(5px)(數值直接相加)

實際來看看 demo:

[embed]

回到最一開始的問題

.card {
  transform: rotate(45deg);
}

@keyframes slide {
  0%   { transform: translateX(0); }
  100% { transform: translateX(100px); }
}
.card:hover {
  animation: slide 0.5s forwards;
  animation-composition: add;
}
/* 結果:rotate(45deg) translateX(0 → 100px) */

keyframes 裡只寫「你新增的動畫部分」,底層值自動保留,不再需要複製。

陷阱 / 注意事項

1. add 附加的順序很重要

rotate(45deg) translateX(100px) 和 translateX(100px) rotate(45deg) 視覺效果不同。add 是把動畫值附加在底層值後面,所以最終結果取決於兩者的順序。

2. accumulate 只對同類型有效

translateX(30px) + rotate(45deg) 用 accumulate 不會加總,類型不同時行為 fallback 到 add。

3. 多個動畫可以分別設定

.box {
  animation: slide 1s, spin 2s;
  animation-composition: add, accumulate;
}

4. 底層值不存在時沒有效果

如果元素本身沒設定 transform,add 和 accumulate 的行為跟 replace 一樣,因為沒有底層值可以合併。

時間軸

animation-composition 不是新提案,它默默走了好幾年才進到所有主流瀏覽器:

2021 年:W3C CSS Working Group 在 CSS Animations Level 2 規範草案中提出 animation-composition,定義 replace / add / accumulate 三種合成模式

2022 年 9 月:Safari 16.0 率先正式支援,是第一個出貨的主流瀏覽器

2023 年 3 月:W3C 發布 CSS Animations Level 2 首份公開工作草案(First Public Working Draft)

2023 年 4 月:Chrome 112 正式支援,同期 Edge 112 跟進

2023 年 7 月:Firefox 115 正式支援 — — 三大引擎全面覆蓋,從此可以放心用瀏覽器支援

Chrome 112+、Firefox 112+、Safari 16.0+、Edge 112+,全主流瀏覽器都支援,可以放心用。

小結

animation-composition 解決了一個寫動畫時很常見的痛點 — — 在已有樣式的基礎上疊加動畫,再也不用把底層值手動複製進 keyframes,也不用多包一層 DOM 了。

replace 是預設,適合大部分情況;add 適合「疊加」而不是「取代」的場景;accumulate 適合同類型數值要做加總的時候。

以上快速分享animation-composition,歡迎補充與留言分享~~


메타데이터
post_id
3cb6805e58d0
slug
動畫疊加不再怕相互覆蓋-淺談-css-animation-composition-3cb6805e58d0
url
https://medium.com/@jamie-li/%E5%8B%95%E7%95%AB%E7%96%8A%E5%8A%A0%E4%B8%8D%E5%86%8D%E6%80%95%E7%9B%B8%E4%BA%92%E8%A6%86%E8%93%8B-%E6%B7%BA%E8%AB%87-css-animation-composition-3cb6805e58d0
canonical_url
https://medium.com/@jamie-li/%E5%8B%95%E7%95%AB%E7%96%8A%E5%8A%A0%E4%B8%8D%E5%86%8D%E6%80%95%E7%9B%B8%E4%BA%92%E8%A6%86%E8%93%8B-%E6%B7%BA%E8%AB%87-css-animation-composition-3cb6805e58d0
author_url
https://medium.com/@jamie-li
status
ok
fetched_at
2026-06-29 02:33:43