開本系列,談談一些有趣的 <code>CSS</code> 題目,題目類型天馬行空,想到什麼說什麼,不僅為了拓寬一下解決問題的思路,更涉及一些容易忽視的 CSS 細節。
解題不考慮相容性,題目天馬行空,想到什麼說什麼,如果解題中有你感覺到生僻的 CSS 屬性,趕緊去補習一下吧。
不斷更新,不斷更新,不斷更新,重要的事情說三遍。
談談一些有趣的CSS題目(一)-- 左邊豎條的實作方法
談談一些有趣的CSS題目(二)-- 從條紋邊框的實作談盒子模型
談談一些有趣的CSS題目(三)-- 層疊順序與堆棧上下文知多少
談談一些有趣的CSS題目(四)-- 從倒影說起,談談 CSS 繼承 inherit
談談一些有趣的CSS題目(五)-- 單行居中,兩行居左,超過兩行省略
談談一些有趣的CSS題目(六)-- 全相容的多列均勻布局問題
談談一些有趣的CSS題目(七)-- 消失的邊界線問題
談談一些有趣的CSS題目(八)-- 純CSS的導航欄Tab切換方案
談談一些有趣的CSS題目(九)-- 巧妙的實作 CSS 斜線
談談一些有趣的CSS題目(十)-- 結構性僞類選擇器
談談一些有趣的CSS題目(十一)-- reset.css知多少
談談一些有趣的CSS題目(十二)-- 深入探讨 CSS 特性檢測 @supports 與 Modernizr
所有題目彙總在我的 Github 。
正文從這裡開始。有的時候,嗯,應該說某些特定場合,我們可能需要下面這樣的動畫效果,漸變 + animation :

假設我們漸變的寫法如下:
按照正常想法,配合 <code>animation</code> ,我們首先會想到在 <code>animation</code> 的步驟中通過改變顔色實作顔色漸變動畫,那麼我們的 CSS 代碼可能是:
上面我們用到了三種顔色:
<code>#ffc700</code> 黃色
<code>#e91e1e</code> 紅色
<code>#6f27b0</code> 紫色
最後,并沒有我們預期的結果,而是這樣的:
我們預期的補間動畫,變成了逐幀動畫。
也就是說,線性漸變是不支援動畫 <code>animation</code> 的,那單純的由一個顔色,變化到另外一個顔色呢?像下面這樣:
發現,單純的單色值是可以發生漸變的:
總結一下,線性漸變(徑向漸變)是不支援 <code>animation</code> 的,單色的 background 是支援的。
查找了下文檔,在 <code>background</code> 附近區域截圖如下:
哪些 CSS 屬性可以動畫?,上面的截圖是不完整的支援 CSS 動畫的屬性,完整的可以戳左邊。
對于 <code>background</code> 相關的,文檔裡寫的是支援 <code>background</code> 但是沒有細說不支援 <code>background: linear-gradient()/radial-gradient()</code> 。猜測原因,可能是由于漸變中加入 animation 的變化對過于消耗性能。
那麼是否我們想要的背景色漸變動畫就無法實作了呢?下面我們就發散下思維看看有沒有其他方式可以達到我們的目标。
上面哪些 CSS 屬性可以動畫的截圖中,列出了與 <code>background</code> 相關還有 <code>background-position</code> ,也就是 <code>background-position</code> 是支援動畫的,通過改變 <code>background-position</code> 的方式,可以實作漸變動畫:
這裡我們還配合了 <code>background-size</code>。首先了解下:
<code>background-position</code>:指定圖檔的初始位置。這個初始位置是相對于以 <code>background-origin</code> 定義的背景位置圖層來說的。
<code>background-size</code>:設定背景圖檔大小。當取值為百分比時,表示指定背景圖檔相對背景區的百分比大小。當設定兩個參數時,第一個值指定圖檔的寬度,第二個值指定圖檔的高度。
通過 <code>background-size: 200% 100%</code> 将圖檔的寬度設定為兩倍背景區的寬度,再通過改變 <code>background-position</code> 的 x 軸初始位置來移動圖檔,由于背景圖設定的大小是背景區的兩倍,是以 <code>background-position</code>的移動是由 <code>0 0</code> -> <code>100% 0</code> 。最終效果如下:
既然 <code>background-position</code> 可以,那麼另一個 <code>background-size</code> 當然也是不遑多讓。與上面的方法類似,隻是這次 <code>background-position</code> 輔助 <code>background-size</code> ,CSS 代碼如下:
效果如下:
通過改變 <code>background-size</code> 的第一個值,我将背景圖的大小由 3 倍背景區大小向 1 倍背景區大小過渡,在背景圖變換的過程中,就有了一種動畫的效果。
而至于為什麼要配合 <code>background-position: 100% 0</code> 。是由于如果不設定 <code>background-position</code> ,預設情況下的值為 <code>0% 0%</code>,會導緻動畫最左側的顔色不變,像下面這樣,不大自然:
上面兩種方式雖然都可以實作,但是總感覺不夠自由,或者随機性不夠大。
不僅如此,上述兩種方式,由于使用了 <code>background-position</code> 和 <code>background-size</code>,并且在漸變中改變這兩個屬性,導緻頁面不斷地進行大量的重繪(repaint),對頁面性能消耗非常嚴重,是以我們還可以試試 <code>transfrom</code> 的方法:
使用僞元素配合 <code>transform</code> 進行漸變動畫,通過元素的僞元素 <code>before</code> 或者 <code>after</code> ,在元素内部畫出一個大背景,再通過 <code>transform</code> 對僞元素進行變換:
實作原理如下圖所示:
我們可以在任意 <code>animation</code> 動畫過程中再加入 <code>scale</code> 、<code>skew</code> 、<code>roate</code> 等變換,讓效果看上去更加逼真随機。效果如下:
上面列出來的隻是部分方法,理論而言,僞元素配合能夠産生位移或者形變的屬性都可以完成上面的效果。我們甚至可以運用不同的緩動函數或者借鑒蟬原則,制作出随機性十分強的效果。
當然,本文羅列出來的都是純 CSS 方法,使用 SVG 或者 Canvas 同樣可以制作出來,而且性能更佳。感興趣的讀者可以自行往下研究。
背景色漸變動畫具體可以運用在什麼地方呢,稍微舉個例子。
除此之外,在背景闆凸顯文字,讓一些靜态底圖動起來吸引眼球等地方都有用武之地。
到此本文結束,如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。