你所不知道的 CSS 動畫技巧與細節(jié)
怕標題起的有點大,下述技巧如果你已經(jīng)掌握了看看就好,歡迎斧正,本文希望通過介紹一些 CSS 不太常用的技巧,輔以一些實踐,讓讀者可以更加深入的理解掌握 CSS 動畫。
廢話少說,直接進入正題,本文提到的動畫不加特殊說明,皆指 CSS 動畫。
正負旋轉相消
嗯。名字起的很奇怪,好像數(shù)學概念一樣。
在動畫中,旋轉是非常常用的屬性,
{
transform: rotate(90deg);
}
那旋轉有一些什么高級點的技巧呢?當然是可以改變 transfrom-origin ,改變旋轉中心點啦。
開個玩笑,改變旋轉中心點這個估計大家都知道了,這里要介紹的技巧是利用父級元素正反兩個方向的旋轉,來制作一些酷炫的 3d 效果。
首先假設一下場景,我們有這樣的一層 HTML 結構:
<div class="reverseRotate">
<div class="rotate">
<div class="content">正負旋轉相消3D動畫</div>
</div>
</div>
樣式如下:

.content 內是我們的主要內容,好了,現(xiàn)在想象一下,如果祖先元素 .rotate 進行正向 linear 360° 旋轉,父級元素 .reverseRotate 進行反向 linear 360° 旋轉,效果回是啥樣?
CSS 代碼如下:
.rotate {
animation: rotate 5s linear infinite;
}
.reverseRotate {
animation: reverseRotate 5s linear infinite;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes reverseRotate {
100% {
transform: rotate(-360deg);
}
}
神奇!因為一正一反的旋轉,且緩動函數(shù)一樣,所以整個 content 看上去依然是靜止的!注意,這里整個 content 靜止的非常重要。
有讀者看到這里就要罵街了,作者你個智障,靜止了不就沒動畫了嗎?哪來的動畫技巧?
別急!雖然看上去是靜止的,但是其實祖先兩個元素都是在旋轉的!這會看上去風平浪靜的效果底下其實是暗流涌動。用開發(fā)者工具選取最外層祖先元素是這樣的:

既然如此,我們繼續(xù)思考,如果我在其中旋轉的一個祖先元素上,添加一些別的動畫會是什么效果?想想就很刺激啊。
為了和文案里面的 3D 動畫扯上關系,我們先給這幾個元素添加 3D 轉換:
div {
transform-style: preserve-3d;
perspective: 500px;
}
接著,嘗試修改上面的旋轉動畫,在內層旋轉上額外添加一個 rotateX:
@keyframes rotate {
0% {
transform: rotateX(0deg) rotateZ(0deg);
}
50% {
transform: rotateX(40deg) rotateZ(180deg);
}
100% {
transform: rotateX(0deg) rotateZ(360deg);
}
}
效果如下:

Wow,這里需要好好理解一下。由于內容 content 層是靜止的但其實外層兩個圖層都在旋轉,通過設置額外的 rotateX(40deg) ,相當于疊加多了一個動畫,由于正反旋轉抵消了,所有整個動畫只能看到旋轉的 rotateX(40deg) 這個動畫,產(chǎn)生了上述的效果。
動畫相同,緩動不同
好的,繼續(xù)下一個小技巧。
有的時候我們頁面存在一些具有相同動畫的元素,為了讓動畫不那么死板,我們可以給相同的動畫,賦予不同的緩動函數(shù),來達到動畫效果。
假設我們有如下的結構:
<div class="container">
<div class="ball ball1"></div>
<div class="ball ball2"></div>
<div class="ball ball3"></div>
</div>
樣式如下:

我們給它們相同的動畫,但是賦予不一樣的緩動函數(shù)(animation-timing-function),就像這樣:
.ball1 {
animation: move 1s ease-in infinite alternate;
}
.ball2 {
animation: move 1s linear infinite alternate;
}
.ball3 {
animation: move 1s ease-out infinite alternate;
}
@keyframes move {
100% {
transform: translateY(5vw);
}
}
這樣,一個簡單的 loading 效果就制作好了。(當然這個技巧比較簡單,學會合理運用是關鍵)

奇妙的緩動
緩動函數(shù) timing-function 在動畫中占據(jù)了非常重要的地位。
當你不想使用 CSS 默認提供的 linear、ease-in、ease-out 之類緩動函數(shù)的,可以自定義 cubic-bezier(1, 1, 0, 0),這里有個非常好用的工具推薦,下面這個網(wǎng)站,可以方便的調出你需要的緩動函數(shù)并且拿到對應的 cubic-bezier 。
過渡取消
我們在制作頁面的時候,為了讓頁面更加有交互感,會給按鈕,陰影,顏色等樣式添加過渡效果,配合 hover 一起使用。
這個是常規(guī)思維,如果我們的元素一開始是沒有過渡效果,只有 hover 上去才給它添加一個過渡,又或者一開始元素是有過渡效果的,當我們 hover 上去時,取消它的過渡,會碰撞出什么樣的火花呢?
使用這個技巧(也許算不上技巧,純粹好玩),我們可以制作出一些有趣的效果,例如下面這個感覺是利用就 JS 才完成的動畫,其實是純 CSS 動畫:

其實就小圓圈是元素默認是帶有 transition 的,只有在 hover 上去的時候,取消它的過渡,簡單的過程:
- 由于一開始它的顏色的透明的,而 hover 的時候會賦予它顏色值,但是由于 hover 時過渡被取消了,所有它會直接顯示。
- hover 離開的時候,它的原本的過渡又回來了,這個時候它會從有顏色到透明值緩慢漸變消失。
可以戳這里感受一下:
CodePen Demo -- Cancle transition
動畫層級的控制,保持動畫層級在最上方
這個問題可能有一點難理解。需要了解 CSS 動畫渲染優(yōu)化的相關知識。
先說結論,動畫層級的控制的意思是盡量讓需要進行 CSS 動畫的元素的 z-index 保持在頁面最上方,避免瀏覽器創(chuàng)建不必要的圖形層(GraphicsLayer),能夠很好的提升渲染性能。
OK,再一次提到了圖形層(GraphicsLayer),這是一個瀏覽器渲染原理相關的知識(WebKit/blink內核下)。

簡單來說,瀏覽器為了提升動畫的性能,為了在動畫的每一幀的過程中不必每次都重新繪制整個頁面。在特定方式下可以觸發(fā)生成一個合成層,合成層擁有單獨的 GraphicsLayer。
需要進行動畫的元素包含在這個合成層之下,這樣動畫的每一幀只需要去重新繪制這個 Graphics Layer 即可,從而達到提升動畫性能的目的。
那么一個元素什么時候會觸發(fā)創(chuàng)建一個 Graphics Layer 層?從目前來說,滿足以下任意情況便會創(chuàng)建層:
- 硬件加速的 iframe 元素(比如 iframe 嵌入的頁面中有合成層)
- 硬件加速的插件,比如 flash 等等
- 使用加速視頻解碼的 元素
- 3D 或者 硬件加速的 2D Canvas 元素
- 3D 或透視變換(perspective、transform) 的 CSS 屬性
- 對自己的 opacity 做 CSS 動畫或使用一個動畫變換的元素
- 擁有加速 CSS 過濾器的元素
- 元素有一個包含復合層的后代節(jié)點(換句話說,就是一個元素擁有一個子元素,該子元素在自己的層里)
- 元素有一個 z-index 較低且包含一個復合層的兄弟元素
本題中說到的動畫層級的控制,原因就在于上面生成層的最后一條:
元素有一個 z-index 較低且包含一個復合層的兄弟元素。
這里是存在坑的地方,首先我們要明確兩點:
- 我們希望我們的動畫得到 GPU 硬件加速,所以我們會利用類似
transform: translate3d()這樣的方式生成一個 Graphics Layer 層。 - Graphics Layer 雖好,但不是越多越好,每一幀的渲染內核都會去遍歷計算當前所有的 Graphics Layer ,并計算他們下一幀的重繪區(qū)域,所以過量的 Graphics Layer 計算也會給渲染造成性能影響。
記住這兩點之后,回到上面我們說的坑。
假設我們有一個輪播圖,有一個 ul 列表,結構如下:
<div class="container">
<div class="swiper">輪播圖</div>
<ul class="list">
<li>列表li</li>
<li>列表li</li>
<li>列表li</li>
<li>列表li</li>
</ul>
</div>
假設給他們定義如下 CSS:
.swiper {
position: static;
animation: 10s move infinite;
}
.list {
position: relative;
}
@keyframes move {
100% {
transform: translate3d(10px, 0, 0);
}
}
由于給 .swiper 添加了 translate3d(10px, 0, 0) 動畫,所以它會生成一個 Graphics Layer,如下圖所示,用開發(fā)者工具可以打開層的展示,圖形外的黃色邊框即代表生成了一個獨立的復合層,擁有獨立的 Graphics Layer 。
<
但是!在上面的圖中,我們并沒有給下面的 list 也添加任何能觸發(fā)生成 Graphics Layer 的屬性,但是它也同樣也有黃色的邊框,生成了一個獨立的復合層。
原因在于上面那條元素有一個 z-index 較低且包含一個復合層的兄弟元素。我們并不希望 list 元素也生成 Graphics Layer ,但是由于 CSS 層級定義原因,下面的 list 的層級高于上面的 swiper,所以它被動的也生成了一個 Graphics Layer 。
使用 Chrome,我們也可以觀察到這種層級關系,可以看到 .list 的層級高于 .swiper:

所以,下面我們修改一下 CSS ,改成:
.swiper {
position: relative;
z-index: 100;
}
.list {
position: relative;
}
這里,我們明確使得 .swiper 的層級高于 .list ,再打開開發(fā)者工具觀察一下:

可以看到,這一次,.list 元素已經(jīng)沒有了黃色外邊框,說明此時沒有生成 Graphics Layer 。再看看層級圖:

此時,層級關系才是我們希望看到的,.list 元素沒有觸發(fā)生成 Graphics Layer 。而我們希望需要硬件加速的 .swiper 保持在最上方,每次動畫過程中只會獨立重繪這部分的區(qū)域。
總結
- GPU 硬件加速也會有坑,當我們希望使用利用類似 transform: translate3d() 這樣的方式開啟 GPU 硬件加速,一定要注意元素層級的關系,盡量保持讓需要進行 CSS 動畫的元素的 z-index 保持在頁面最上方。
- Graphics Layer 不是越多越好,每一幀的渲染內核都會去遍歷計算當前所有的 Graphics Layer ,并計算他們下一幀的重繪區(qū)域,所以過量的 Graphics Layer 計算也會給渲染造成性能影響。
- 可以使用 Chrome ,用上面介紹的兩個工具對自己的頁面生成的 Graphics Layer 和元素層級進行觀察然后進行相應修改。
- 上面觀察頁面層級的 chrome 工具非常吃內存?好像還是一個處于實驗室的功能,分析稍微大一點的頁面容易直接卡死,所以要多學會使用第一種觀察黃色邊框的方式查看頁面生成的 Graphics Layer 這種方式。
數(shù)字動畫
很多技巧單獨拿出來可能都顯得比較單薄,我覺得最重要的是平時多積累,學會融會貫通,在實際項目中靈活組合運用,最近項目需要一個比較富有科技感的數(shù)字計數(shù)器,展示在線人數(shù)的不斷增加。因為是內部需求,沒有設計稿,靠前端自由發(fā)揮。
運用了上面提到的一些小技巧,參考了一些 CodePen 上的效果,整了個下述的 3D 數(shù)字計數(shù)效果,純 CSS 實現(xiàn),效果圖如下:

總結
以上所述是小編給大家介紹的你所不知道的 CSS 動畫技巧與細節(jié),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章

CSS3打造的現(xiàn)代交互式登錄界面詳細實現(xiàn)過程
本文介紹CSS3和jQuery在登錄界面設計中的應用,涵蓋動畫、選擇器、自定義字體及盒模型技術,提升界面美觀與交互性,同時優(yōu)化性能和可訪問性,感興趣的朋友跟隨小編一起看看吧2025-06-20CSS普通流、浮動與定位網(wǎng)頁布局三大機制及最佳實踐
本文給大家講解CSS 的三種核心布局機制——普通流(Normal Flow)、浮動(Float)和定位(Positioning)對于創(chuàng)建靈活、響應式的網(wǎng)頁至關重要,本文將深入探討這三種機制的工作原2025-06-19
css實現(xiàn)角標效果并帶有文章或圖標效果(完整代碼)
文章介紹如何用CSS實現(xiàn)角標效果,通過.active類結合::after和::before偽元素,利用定位、邊框和旋轉創(chuàng)建紅色邊框與白色三角形的提示標志,適用于按鈕或卡片元素的視覺增強設計2025-06-19CSS Anchor Positioning重新定義錨點定位的時代來臨(最新推薦)
CSS Anchor Positioning是一項仍在草案中的新特性,由 Chrome 125 開始提供原生支持需啟用實驗 flag,它允許你在 CSS 中通過錨點(anchor)來相對于任意 DOM 元素定位,本文2025-06-17CSS中的Static、Relative、Absolute、Fixed、Sticky的應用與詳細對比
CSS 中的 position 屬性用于控制元素的定位方式,不同的定位方式會影響元素在頁面中的布局和層疊關系,以下是 static、relative、absolute、fixed、sticky 的詳細對比和應用2025-06-17CSS place-items: center解析與用法詳解
place-items: center; 是一個強大的 CSS 簡寫屬性,用于同時控制 網(wǎng)格(Grid) 和 彈性盒(Flexbox) 布局中的對齊方式,本文給大家介紹CSS place-items: center; 詳解與用法2025-06-17
在日常開發(fā)中,我們經(jīng)常需要讓某個元素占據(jù)容器的剩余空間,本文將介紹5種不同的方法來實現(xiàn)這個需求,并分析各種方法的優(yōu)缺點,感興趣的朋友一起看看吧2025-06-17CSS中前端單位 px、vw、vh 等的區(qū)別與使用建議
CSS單位區(qū)別與使用場景總結:px絕對、vw/vh響應式,%繼承父尺寸,em/rem文字縮放,vmin/vmax適應寬高變化,固定布局用px或%,響應式布局用vw/vh/rem,文字用em或rem,本文給大家2025-06-16- 這篇文章主要介紹了CSS 樣式表的四種應用方式及css注釋的應用小結,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2025-05-21
- 在CSS布局中,padding屬性是控制元素內容與其邊框之間距離的關鍵工具,本文介紹CSS基礎中padding,通過本文的介紹,我們深入了解了padding的基本概念、簡寫方法以及它對元2025-05-16




