> 原文出處:http://www.w3cplus.com/css3/css-secrets/random-backgrounds.html
## 問題
雖然平鋪幾何圖形很棒,但看起來還是有點乏味。**而在自然界中,萬事萬物皆有不同。**即使是在相似中,也充滿了變化和隨機因素。你可以看一看花圃:雖然花朵具有一致的艷麗,但也各有各的亮點。這個世界上沒有任何兩朵花是相同的。這就是為什么我們要嘗試讓背景圖案接近真實,而且我們也在嘗試讓平鋪的元素之間盡量減少縫隙,讓它們顯得渾然天成自成一體,但是這也會讓樣式文件的大小超出我們的預期。
> 當你發現了某些獨特的特性——比如木頭紋理上特定距離就會出現的結,就會打破隨機性這種感覺 — Alex Walker,?[The Cicada Principle and Why It Matters to Web Designers](http://sitepoint.com/the-cicada-principle-and-why-it-matters-to-web-designers)
模擬隨機是一件非常具有挑戰性的事情,因為 CSS 并沒有任何創造隨機性的能力。讓我們重新拿起條紋這個示例,假設我們想要得到擁有各種顏色和寬度的垂直條紋(讓我們簡化為四種顏色吧),并且還要讓它們之間過渡自然。我們的第一個想法可能就是創建一個漸變:
~~~
background: linear-gradient(90deg,
#fb3 15%, #655 0, #655 40%,
#ab4 0, #ab4 65%, hsl(20, 40%, 90%) 0);
background-size: 80px 100%;
~~~
就像下圖看到的那樣

*圖注:實現偽隨機條紋的初次嘗試,其中所有的顏色都是由相同的線性漸變生成的*
非常明顯就分辨出了重復元素,這主要是因為它只重復了?`80px`(`background-size`)。我們可以做得更好嗎?
## 解決方案
對于這一問題,我的第一個想法就是將整個的條紋分成不同塊,然后增加這些塊的隨機性:一個基色和三個條紋層,在不同的距離上實現平鋪。通過硬編碼顏色過渡點的位置,我們可以改變條紋的寬度,通過使用?`backgroud-size`,我們可以控制間距,最終就能實現上面的初步設想了:
~~~
background: hsl(20, 40%, 90%);
background-image:
linear-gradient(90deg, #fb3 10px, transparent 0),
linear-gradient(90deg, #ab4 20px, transparent 0),
linear-gradient(90deg, #655 20px, transparent 0);
background-size: 80px 100%, 60px 100%, 40px 100%;
~~~
因為最頂層的平鋪將會最容易被注意到(因為它覆蓋了所有的圖層),所以我們對最上面的一層施加最大的間歇性間距(在本例中,就是桔黃色條紋)。

*圖注:第二次嘗試,通過不同的?`background-size`?讓不同的圖層發生重疊;虛線框內的圖案是用來平鋪的圖案*
正如上圖中所看到的那樣,整體看起來隨機多了,但如果我們仔細觀察,還是能意識到每?`240px`?就會有一次重復。也就是說,在此類組合中,所有重復塊的偏移量就是第一個非重復條紋終點位置的一倍或數倍。也許你還記得在學校里我們學過的最小公倍數(LCM,Least Common Multiple),它是一個整數集合中所有整數的一倍或多倍。因此,這里條紋塊的大小就是背景大小的最小公倍數,即?`40/60/80`,它們的最小公倍數就是?`240`。
上面的示例就遵循了這一不易察覺的隨機性,所以我們需要增大平鋪條紋塊的大小。感謝數學的存在,無需漫長和痛苦的計算我們就可以實現它,因為我們已經知道了答案。為了達到最大的最小公倍數,那么這些數之間必須互質。在本例中,最小公倍數就是由它們得出來的。比如,`3/4/5`?就互為質數,所以它們的最小公倍數就是?`3 × 4 × 5 = 60`。讓數值互為質數的最簡單方式就是讓它們是質數,在數學上質數和其他任何數都互為質數。質數的列表在網絡上隨處可見。
為了保持最大的隨機性,我們甚至使用質數來設計條紋的寬度。這就是我們的代碼:
~~~
background: hsl(20, 40%, 90%);
background-image:
linear-gradient(90deg, #fb3 11px, transparent 0),
linear-gradient(90deg, #ab4 23px, transparent 0),
linear-gradient(90deg, #655 41px, transparent 0);
background-size: 41px 100%, 61px 100%, 83px 100%;
~~~
是的,代碼很難看,但是效果如下圖所示:

*圖注:最終的條紋,使用質數來增加隨機性*
現在我們的條紋至少?`41 × 61 × 83 = 207583px`?才會平鋪一次,完全超出了一個屏幕分辨率所能容納的數量。
上面的技巧(使用質數增加背景平鋪時的隨機性)被稱為 “The Cicada Principle”,由 Alex Walker 第一次提出。值得注意的是,這不僅僅對背景有用,而且對需要平鋪的任何事情都有用。其他的應用包括但不限于:
* 為一個圖庫中圖片的旋轉角度增加一點點隨機性,可以使用?`:nth-child(an)`?選擇器,其中?`a`?為質數。
* 為動畫的運動過程添加一些隨機性,那么可以添加多個以質數為時間長度的持續時間(點擊這里查看[示例](http://codepen.io/airen/pen/WQoBRR))
> 向提出這一技巧的 Alex Walker 致敬,?[The Cicada Principle and Why It Matters to Web Designers](http://www.sitepoint.com/the-cicada-principle-and-why-it-matters-to-web-designers/)。?[Eric Meyer](http://meyerweb.com/)?隨后提出了?[Cicadients](http://meyerweb.com/eric/thoughts/2012/06/22/cicadients/)?這一概念, 其中就包含了將該技巧通過 CSS 漸變添加到背景圖片上。Dudley Storey 也就該概念發表了[大量非常有價值的文章](http://demosthenes.info/blog/840/Brood-X-Visualizing-The-Cicada-Principle-In-CSS).
## 總結
前面介紹的內容,不管是使用漸變實現的線性漸變還是徑向漸變,或者說是復雜的紋理背景,都是具有一定的規律性。在這一節中主要向大家闡述了如何實現隨機性的背景圖效果。