> 原文出處:http://www.w3cplus.com/css3/css-secrets/striped-backgrounds.html
## 問題
和其他視覺設計相關的媒體一樣,在 Web 上各類大小、顏色、角度不同的紋理也非常流行。不過,實現這些紋理的技術卻并不理想。通常,我們需要創建獨立的位圖,如果有需求變更的話都需要重新更改文件。有些開發者使用 SVG 替代位圖,但是 SVG 仍然是一種獨立的文件,而且其語法也不夠友好。那么是否有一種出色的方法讓我們直接在 CSS 中創建紋理呢?你會驚喜的發現,我們將在下面的介紹中逐步解決這一問題。
## 解決方案
首先,假設我們需要一個簡單地垂直漸變,顏色從?`#fb3`?到?`#58a`:

*圖1注:我們初始化的漸變效果*
~~~
background: linear-gradient(#fb3, #58a);
~~~
現在,讓我們將兩種顏色的過渡點調的更近一些:

*圖2注:現在漸變占據了整體`60%`的高度,其余的部分都是純色;顏色過渡點的位置在這里使用虛線標識出來*
~~~
background: linear-gradient(#fb3 20%, #58a 80%);
~~~
到此為止,容器頂部`20%`的部分是純粹的?`#fb3`,底部`20%`的部分是純粹的?`#58a`,所以實際上漸變的部分只占有了容器的`60%`。那么如果我們將顏色過渡點(color stops)調整地更近一些(比如?`40%`?和?`60%`,如下圖所示),那么漸變的部分就會更小了。這就讓我們很自然地聯想到,如果顏色過渡點相同會發生什么呢?

*圖3注:現在漸變占據了整體`20%`的高度,其余的部分都是純色;顏色過渡點的位置在這里使用虛線標識出來*
~~~
background: linear-gradient(#fb3 50%, #58a 50%);
~~~
> "如果多個顏色過渡點的位置相同,那么就會在兩個顏色之間生成一個無限小的過渡。實際效果就是,一個顏色不再會流暢地過渡到下一個顏色了,而是會突然變成下一個顏色。" —?[CSS Image Values Level 3](http://w3.org/TR/css3-images)
正如下圖中看到的那樣,已經看不到顏色過渡區域了,只有兩種純色,每種純色占有容器一半的高度。可以說,我們已經創建了兩個寬大的水平紋理。

*圖4注:現在兩個顏色的過渡點位置重合了*
因為漸變本質上就是?`backgroud-image`,所以我們可以像對待?`background-image`?一樣使用?`background-size`?調整大小:
~~~
background: linear-gradient(#fb3 50%, #58a 50%);
background-size: 100% 30px;
~~~
就像下圖看到的那樣

*圖5注:我們生成的背景沒有使用平鋪*
我們將兩條紋理都縮小到了?`15px`?的高度。因為背景是可以平鋪的,所以我們可以讓整個容器填充這種水平紋理了:

*圖6注:最終的水平漸變*
當然,我們還可以創建不等寬的條紋,秘訣就是調節一下顏色過渡點的位置:
~~~
background: linear-gradient(#fb3 30%, #58a 30%);
background-size: 100% 30px;
~~~
為了避免每次需求變更都需要修改兩處顏色過渡點的重復工作,我們可以充分利用規范中介紹的原理:
> “如果某個顏色過渡點的位置小于它之前的顏色過渡點,那么該顏色過渡點的位置就會被重置為所有在它前面的顏色過渡點的最大位置。” —?[CSS Images Level 3](http://w3.org/TR/css3-images)
這意味著如果我們將第二個顏色過渡點設置為`0`,那么它實際的位置就會被瀏覽器重置為它前面顏色過渡點的最大位置,而這個位置恰恰就是我們需要的過渡位置。因此,下面的代碼不僅僅是和下圖 具有同樣的效果,而且更加簡潔、更具有可維護性:

*圖7注:不等寬條紋*
~~~
background: linear-gradient(#fb3 30%, #58a 0);
background-size: 100% 30px;
~~~
創建更多顏色的紋理和創建兩種顏色的問題同樣簡單。比如,下面的代碼塊創建了三種顏色的紋理:

*圖8注:三色條紋*
~~~
background: linear-gradient(#fb3 33.3%,
#58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 45px;
~~~
## 垂直紋理
水平紋理非常容器創建,但是在 Web 上并不是所有的紋理都是水平的,此外還有很多紋理是垂直的

*圖9注:垂直條紋,上面:背景沒有使用平鋪;下面:平鋪之后的條紋*
而且,在視覺上最受歡迎的紋理可能是傾斜的紋理。值得慶幸的是,CSS 的漸變可以幫助我們實現這樣的效果,只是實現的難度各種不同。
實現垂直紋理的代碼和水平紋理的非常相似,只有一個主要的差異:一個指定漸變方向的參數。我們可以通過指定這個參數來創建水平紋理,不過對于此次要創建的垂直紋理,使用它的默認值即可(`to bottom`)。此外,同樣需要創建一個不同的`background-size`,原因很明顯:
~~~
background: linear-gradient(to right, /* or 90deg */
#fb3 50%, #58a 0);
background-size: 30px 100%;
~~~
## 斜紋
在實現了水平紋理和垂直紋理之后,我們可能會嘗試通過?`background-size`?和漸變方向來實現傾斜的紋理(`45°`),就像這樣的代碼:
~~~
background: linear-gradient(45deg,
#fb3 50%, #58a 0);
background-size: 30px 30px;
~~~
不過,就像下圖所示,效果非常不好。

*圖10注:第一次創建斜紋的失敗效果*
究其原因,就是因為我們只是將每一條紋理旋轉了?`45°`,旋轉的并不是圖形整體。讓我們回憶一下使用位圖創建斜紋的方法,其中引入的位圖和下圖相類似。

*圖11注:這就是創建斜紋的拼接圖,看起來是不是很像?*
它包含了四條紋理,而不是這里的兩條,所以看起來像是無縫連接的。這就是我們需要在 CSS 中重新創建的紋理,所以我們需要更多的顏色過渡點:
~~~
background: linear-gradient(45deg,
#fb3 25%, #58a 0, #58a 50%,
#fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
~~~
完成后的效果:

*圖12注:`45°`?斜紋;虛線用來標識復用的區塊*
如你所見,雖然我們成功的創建了斜紋,但是看起來比水平和垂直紋理要窄一些。為了回答這個問題,我們需要使用學校里學到的勾股定理來計算直角三角形的各邊變長。勾股定理指出,最長邊等于其他兩邊的平方和。在直接三角形中,兩條短邊相等所以么最長邊就等于:

在我們創建的這個斜紋中,`background-size`?指定的就是三角形最長邊的邊長,因此紋理的寬度就是直角邊的長度。你可以看下圖,獲得更清晰的解釋。

圖13注:大小為?`20px`?的?`background-size`?將會生成寬度為的條紋
這就是說,如果想要獲得原來?`15px`?的寬度,就需要將?`background-size`?指定為:
~~~
background: linear-gradient(45deg,
#fb3 25%, #58a 0, #58a 50%,
#fb3 0, #fb3 75%, #58a 0);
background-size: 42.426406871px 42.426406871px;
~~~
最終效果:

*圖14注:`45°`斜紋的最終效果;值得注意的是,現在條紋的寬度和其示例中條紋的寬度一致了*
不過,除非某人拿槍威脅你非得讓斜紋寬度為?`15px`(這種情況你你死定了,因為根號二是一個有理數,所以這里雖然使用了一個高精度的數值,但仍然不是它的值),否則我建議你可以約取一個數值,比如?`42.4px`?或者?`42px`。
## 更出色的斜紋
上一節介紹的方法使用起來不夠靈活。如果我們讓斜紋傾斜?`60°`、`30°`、`3.1415926535°`?時又該怎么處理呢?如果我們只是想修改一下角度,效果看起來還是不錯的(下圖是一個失敗的嘗試)。

*圖15注:失敗的?`60°`?斜紋*
所幸的是,有一種更好的方式創建斜紋。很少人知道的是,其實?`linear-gradient()`?和?`radial-gradient()`也有一個實現平鋪效果的版本:`repeating-linear-gradient()`?和?`repeating-radial-gradient()`。它們的原理基本相同,只有一個差別:顏色過渡點也可以無限平鋪,知道填充整個圖片。所以,可以這樣平鋪漸變:

*圖16注:平鋪后的線性漸變*
~~~
background: repeating-linear-gradient(45deg,
#fb3, #58a 30px);
~~~
這段代碼與下面的線性漸變代碼等效:
~~~
background: linear-gradient(45deg,
#fb3, #58a 30px,
#fb3 30px, #58a 60px,
#fb3 60px, #58a 90px,
#fb3 90px, #58a 120px,
#fb3 120px, #58a 150px, ...);
~~~
你可能已經猜到了,平鋪線性漸變同樣適用于斜紋。因為它們的平鋪特性,這意味我們的整個背景都可以使用漸變圖片來實現了。因此,我們無需再擔心創建平鋪小圖片的無縫連接問題了。
為了做一下比較,下圖中的背景也可以使用下面的平鋪漸變來實現:

*圖17注:`60°`?條紋*
~~~
background: repeating-linear-gradient(45deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
~~~
這種方法最明顯的優勢就是減少了重復:如果需要修改顏色,那么只需修改兩處即可完成,而之前則需要三次。另一個值得注意的地方在于,現在我們可以使用顏色過渡點來控制顏色的寬度,而不再使用?`background-size,background-size`?專注于控制元素的尺寸。這意味著定義條紋的寬度會更加直接,無需再計算 根號二這樣的數了!
不過,最大的好處還在于現在可以任意調整傾斜的角度了,而且無需再考慮紋理塊之間的無縫連接問題。比如,這里有一個?`60°`?的條紋示例:

~~~
background: repeating-linear-gradient(60deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
~~~
簡單到只需調節角度即可實現!值得注意的是,使用這種方法創建兩條斜紋的話,我們需要設置四個顏色過渡點。這意味著,使用第一種方式創建水平和垂直紋理更方便,而使用這種方式更適合于創建斜紋。如果我們要創建?`45°`的斜紋,那么可以組合使用這兩種方法,核心是使用?`repeating-linear-gradient`?來縮簡重復代碼:
~~~
background: repeating-linear-gradient(45deg,
#fb3 0, #fb3 25%, #58a 0, #58a 50%);
background-size: 42.426406871px 42.426406871px;
~~~
> **展望:擁有兩個位置的顏色過渡點**?在不久的將來,我們將可以為同一個顏色過渡點設定兩個位置,現在對此已經有了一個簡單地規劃,并添加進了?[CSS Image Values Level 4](http://w3.org/TR/css4-images)。在這里,可以將新語法看成一個簡寫形式,只需要添加兩個顏色過渡點以及不同的過渡位置,就可以創建一個紋理。舉個例子來說,我們可以將上圖的斜紋代碼修改為:?`background: repeating-linear-gradient(60deg, #fb3 0 15px, #58a 0 30px);`?這樣的做不僅讓代碼更加容易理解,而且也更具有可維護性:不再需要重復定義過渡點顏色,只需編寫一次即可實現紋理。不幸的是,在本書編寫的時候,還沒有任何瀏覽器支持它。
## 靈活可擴展的精致斜紋
通常來說,我們的斜紋并不是由多種不同顏色組成的,往往只是一種顏色的變化就可以構造成精致的紋理。比如,看看下面這個紋理:
~~~
background: repeating-linear-gradient(30deg,
#79b, #79b 15px, #58a 0, #58a 30px);
~~~
具體效果如下:

*圖18注:添加了細微亮色的條紋*
你可以看到,組成該紋理的是同一色彩衍生的兩種顏色,其中一種比另一種的亮度更高而已。不過,我們無法從代碼中分辨出兩個顏色之間的關系。此外,如果我們想改變色彩,那么至少需要在四個地方進行編輯。
所幸的是,這里有一個更好的編寫方式:不再為紋理指定具體的顏色,只使用深色定義?`background-color`,然后它上面添加一個半透明白色的紋理:
~~~
background: #58a;
background-image: repeating-linear-gradient(30deg,
hsla(0,0%,100%,.1),
hsla(0,0%,100%,.1) 15px,
transparent 0, transparent 30px);
~~~
最終的結果上圖一模一樣,但我們現在只需編輯一處就可以修改成不同的色彩。使用這個方法,我們甚至還得到了一個額外的好處,那就是為低版本瀏覽器提供了降級處理,當瀏覽器不支持漸變時,就會顯示深色背景。在下一節中,我們將會看到,使用透明區域的漸變圖案,可以讓我們創建更復雜的圖案。
## 擴展閱讀
* [CSS3 Gradient](http://www.w3cplus.com/content/css3-gradient)
* [再說CSS3漸變——線性漸變](http://www.w3cplus.com/css3/new-css3-linear-gradient.html)
* [再說CSS3漸變——徑向漸變](http://www.w3cplus.com/css3/new-css3-radial-gradient.html)
* [Web頁面的紋理背景設計與資源](http://www.w3cplus.com/source/background-patterns-designs-and-resources-for-websites.html)
* [37個CSS3 Patterns Gallery](http://www.w3cplus.com/demo/413.html)
* [Stripes in CSS](https://css-tricks.com/stripes-css/)
* [CSS3 Patterns, Explained](https://24ways.org/2011/css3-patterns-explained/)
* [SVG Patterns Gallery](http://philbit.com/svgpatterns/)
* [CSS3 Patterns Gallery](http://lea.verou.me/css3patterns/)
* [How to Use SVG Patterns](http://designmodo.com/svg-patterns/)
## 總結
這一節從CSS3的線性漸變開始,詳細介紹了如何通過線性漸變配合`background-size`實現雙色、多色斑馬紋理背景效果。而且將線性漸變的方向換成角度值,可以實現斜紋紋理背景。當然,事實上,不同的背景(漸變做的背景)配合`background-size`可以實現更多的紋理背景。感興趣的同學,看完之后可以參閱文章中的擴展資源,了解更多相關知識。