原文出處:http://www.w3cplus.com/css3/css-secrets/complex-background-pattern.html
在上一節(jié)中,我們學(xué)習(xí)了如何使用 CSS 漸變創(chuàng)建各種類型的條紋。不過,條紋并不能代表所有的背景圖案,最多只能算是背景中的幾何圖案。此外,我們還會常常用到許多類型的背景,比如網(wǎng)格、波爾卡圓點、棋盤格等等。
值得慶幸的是,CSS 的漸變屬性就可以幫我們創(chuàng)建這些背景圖案。雖然幾乎可以使用 CSS 的漸變創(chuàng)建各種類型的幾何圖案,但是這些背景圖案的效果并不具有實用性。如果開發(fā)中稍不注意,那么代碼就會迅速變得冗雜和繁瑣。CSS 的背景圖案也是非常適合使用 CSS 預(yù)處理器來處理的問題之一,比如可以使用?Sass?來減少重復(fù)背景圖案中的重復(fù)工作。
在 2011 年的時候,我的?CSS3 圖案集?就展示了大量的 CSS 漸變圖案。之后在 2011 年和 2012 年期間,有大量和 CSS 漸變相關(guān)的文章、書籍和會議引用了它們,甚至?xí)粸g覽器廠商拿來調(diào)整瀏覽器在漸變方面的功能。不過,并不是每一個模式都是可以用于線上產(chǎn)品的,有一些只是用來演示 CSS 漸變的能力,但是具體的代碼往往過于冗雜。對于這些情況,SVG 顯然是個更好的選擇。如果你想了解更多的 SVG 信息,可以查看?SVG Patterns,該網(wǎng)站展示了大量 SVG 版本的 CSS 圖案集。
在本章中,我們將會著重創(chuàng)建簡單且實用的圖案。
當(dāng)我們只能使用一次漸變時,往往就限制了背景圖案的種類。下面將要展示給各位的魔幻效果就是要組合多個漸變,讓它們交叉重疊。最簡單的圖案就是使用交叉重疊的水平和垂直條紋創(chuàng)建各種類型的網(wǎng)格。比如,下面的代碼就是用來創(chuàng)建懷舊風(fēng)格的桌布圖案:
圖注:由兩個漸變組成的桌布圖案(這里的透明色就是傳統(tǒng)的灰色棋盤格)
background: white;
background-image: linear-gradient(90deg,
rgba(200,0,0,.5) 50%, transparent 0),
linear-gradient(
rgba(200,0,0,.5) 50%, transparent 0);
background-size: 30px 30px;
在某些情況下,我們會想要調(diào)整網(wǎng)格中單元格內(nèi)部的尺寸,而又不影響單元格整體的大小。這也是一種很好地情境,讓我們使用固定長度代替百分比來設(shè)置過渡點的位置:
background: #58a;
background-image:
linear-gradient(white 1px, transparent 0),
linear-gradient(90deg, white 1px, transparent 0);
background-size: 30px 30px;
效果如圖所示
圖注:一個基礎(chǔ)的藍圖網(wǎng)格圖案,每個單元格的邊框為1px
,邊框的寬度和整個單元格的寬度無關(guān)
上圖是一個具有?1px
?白線的網(wǎng)格,網(wǎng)格中的每個單元格保持了?30px
?的大小。就像在上一節(jié)的 “靈活可擴展的精致斜紋” 部分所說,最初設(shè)定的背景色也是一種降級處理的技巧。
總體來看,這個網(wǎng)格圖案是高可維護性代碼(雖然其中仍然有一些重復(fù)代碼)的典范:
170b
的代碼量,如果使用 SVG 的話是遠遠無法如此精簡的將 CSS 圖案的文件黏貼到?bytesizematters.com?這個網(wǎng)站,就可以計算出文件大小
我們甚至可以交叉多層不同寬度和顏色的網(wǎng)格來創(chuàng)建一個更真實的網(wǎng)格(類似藍圖圖紙,如下圖):
圖注:更復(fù)雜的藍圖圖案,主要由兩個網(wǎng)格組成,每個網(wǎng)格都有不同的樣式
background: #58a;
background-image:
linear-gradient(white 2px, transparent 0),
linear-gradient(90deg, white 2px, transparent 0),
linear-gradient(hsla(0,0%,100%,.3) 1px,
transparent 0),
linear-gradient(90deg, hsla(0,0%,100%,.3) 1px,
transparent 0);
background-size: 75px 75px, 75px 75px,
15px 15px, 15px 15px;
到目前為止,我們只是使用了線性漸變來創(chuàng)建背景圖案。在此之外,徑向漸變通常非常有用,它可以幫助我們創(chuàng)建圓形、橢圓形,或者是這些圖形的部分。使用徑向漸變創(chuàng)建的最簡單圖案就是大量的圓點,如下圖:
圖注:一個點集;虛線框內(nèi)是用來平鋪的圖案
background: #655;
background-image: radial-gradient(tan 30%, transparent 0);
background-size: 30px 30px;
誠如所見,這種圖案往往用處不大。不過,接下來我們可以使用兩個徑向漸變的組合,通過設(shè)定不同的?background-size
?來創(chuàng)建類似波爾卡圓點的圖案:
圖注:波爾卡圓點圖案;虛線框內(nèi)的兩個圖案都是是用來平鋪的圖案
background: #655;
background-image: radial-gradient(tan 30%, transparent 0),
radial-gradient(tan 30%, transparent 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
值得注意的是,為了實現(xiàn)這種效果,就必須讓第二個漸變的?background-position
?為?background-size
?的一半。不幸的是,這意味著當(dāng)我們需要修改背景大小時,就至少只需在四個地方進行修改。雖然無法定論這樣的代碼已經(jīng)混亂了,但可以確信的說,我們的代碼已經(jīng)接近混亂邊緣了。如果你正在使用預(yù)處理器,那么你就可以將它轉(zhuǎn)換成一個混合宏:
@mixin polka($size, $dot, $base, $accent) {
background: $base;
background-image:
radial-gradient($accent $dot, transparent 0),
radial-gradient($accent $dot, transparent 0);
background-size: $size $size;
background-position: 0 0, $size/2 $size/2;
}
現(xiàn)在,當(dāng)我們再次創(chuàng)建波爾卡圓點時,只需像下面這樣做就可以了:
@include polka(30px, 30%, #655, tan);
棋盤格圖案在現(xiàn)實世界中有大量的應(yīng)用。比如,輕質(zhì)的棋盤格可以用來替換古板的純色背景,讓頁面顯得更有趣。此外,在眾多的 UI 設(shè)計中,灰色的棋盤格背景已經(jīng)被廣泛地理解為了透明效果。使用 CSS 創(chuàng)建一個棋盤格圖案是可能的,但是其中的艱辛將會超出我們的想象。
圖注:灰色棋盤格圖案往往用來表示透明區(qū)域;如果使用圖片平鋪的方式實現(xiàn)這種效果,那么虛線框內(nèi)的圖案就是要平鋪的圖案
正如上圖所示,一個典型的棋盤格格子,有兩個不同顏色的正方形不斷重復(fù)組成的。乍看之下,好像很容易就可以創(chuàng)建出來:只需要創(chuàng)建兩個位置不同的矩形嘛。這樣做對嗎?顯然并沒有那么簡單。雖然我們可以使用 CSS 漸變創(chuàng)建矩形,但是如果矩形周圍沒有可用空間的話,最終的效果就會變成一個純色背景。實際上,我們是無法使用 CSS 漸變創(chuàng)建具有額外空間的矩形。如果你對此有所疑問,可以動手試一試,當(dāng)你讓漸變平鋪時,就會生成類似下圖的效果。
圖注:平鋪一個四周有空白的正方形;虛線框內(nèi)是用于平鋪的圖案
實現(xiàn)這種效果的技巧就是,使用兩個直角三角形拼接成正方形。在前面的集結(jié)中,我們已經(jīng)知道了如何創(chuàng)建直角三角形。如下圖所示:
為了讓你回憶起來,你可以看看下面的代碼:
background: #eee;
background-image:
linear-gradient(45deg, #bbb 50%, transparent 0);
background-size: 30px 30px;
這個時候你可能疑惑了,這樣做有什么用嗎。當(dāng)然有用,如果我們想合成類似下圖效果:
那樣的正方形,我們就會得到一個純色。不過,如果我們將三角形的長度減半,那么它們就會占有原來空間的八分之一,而不是現(xiàn)在的二分之一,這種情況下又會是怎樣的效果呢?我們只需將顏色過渡點的位置從?50%
?調(diào)整為?25%
,即可完成這一調(diào)整。最后的效果就是下圖這樣的直角三角形了。
圖注:周圍有大量空白的直接三角形
與上面道理相同,只需翻轉(zhuǎn)顏色過渡點即可創(chuàng)建反方向的直接三角形:
圖注:翻轉(zhuǎn)顏色過渡點之后,得到相反方向的三角形
background: #eee;
background-image:
linear-gradient(45deg, transparent 75%, #bbb 0);
background-size: 30px 30px;
展望:錐形漸變(Conical gradients) 未來,我們創(chuàng)建棋盤格背景將不再需要費心地交叉覆蓋三角形。在?CSS Image Values Level 4?中,定義了一系列新的漸變函數(shù)來生成錐形漸變(又名,“angle gradients”)。這些漸變從俯視的角度來看就像一個圓錐,所以得名錐形漸變。錐形漸變由一系列的顏色過渡點組成,并且從一個固定點開始旋轉(zhuǎn)變化。比如,使用下面的代碼就可以創(chuàng)建一個色調(diào)取色盤:?
background: conic-gradient(red, yellow, lime, aqua, blue, fuchsia, red); `` 錐形漸變在很多情況下都非常有用,比如星群、金屬拉絲等效果,當(dāng)然也包括棋盤格效果。未來,創(chuàng)建一個類似棋盤格只需使用一個漸變就可以實現(xiàn):
?background: repeating-conic-gradient(#bbb 0, #bbb 25%, #eee 0, #eee 50%); background-size: 30px 30px; ``` 不幸的是,本書寫作的時候的還沒有任何瀏覽器實現(xiàn)了這一漸變。
如果我們創(chuàng)建兩個漸變,猜猜看會有什么結(jié)果呢?
background: #eee;
background-image:
linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0);
background-size: 30px 30px;
首先,結(jié)果就像下圖所示一般,它并不像我們所要實現(xiàn)的效果。不過,我們只需要將第二個漸變的位置移動?background-size
的一半,就可以將它們合并成正方形了:
圖注:合并兩個三角形圖案
background: #eee;
background-image:
linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0);
background-position: 0 0, 15px 15px;
background-size: 30px 30px;
你能猜到最終的結(jié)果會是什么樣子嗎?它就是我們想要實現(xiàn)的棋盤格:
圖注:三角形合并后變成了正方形,并且在周圍保持了空白區(qū)域;虛線框內(nèi)的兩個圖案是用于平鋪的圖案,第二個漸變用深色標(biāo)志
請注意,這只是棋盤格的一半。如果想創(chuàng)建一個完整的正方形棋盤格,只需重復(fù)一下上面的兩條漸變,然后調(diào)整一下位置即可,有點類似創(chuàng)建波爾卡圓點的操作:
background: #eee;
background-image:
linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0),
linear-gradient(45deg, #bbb 25%, transparent 0),
linear-gradient(45deg, transparent 75%, #bbb 0);
background-position: 0 0, 15px 15px,
15px 15px, 30px 30px;
background-size: 30px 30px;
最終的結(jié)果就是和下圖所示的棋盤格了。
此外,通過合并對立的三角形(比如,第一個對第二個,第三個對第四個)、添加暗色半透明的基色,可以提高代碼的可維護性,無需調(diào)整頂層的顏色,只需更改基色即可應(yīng)對新的需求:
background: #eee;
background-image:
linear-gradient(45deg,
rgba(0,0,0,.25) 25%, transparent 0,
transparent 75%, rgba(0,0,0,.25) 0),
linear-gradient(45deg,
rgba(0,0,0,.25) 25%, transparent 0,
transparent 75%, rgba(0,0,0,.25) 0);
background-position: 0 0, 15px 15px;
background-size: 30px 30px;
現(xiàn)在,我們用兩個漸變替換了四個漸變,代碼總體簡練多了。如果需要改變顏色或者單元格大小,則至少需要修改四處地方。在這一個問題上,使用預(yù)處理器的混合宏顯然是一個明智之舉。比如,可以在 Sass 中這樣處理:
@mixin checkerboard($size, $base, $accent: rgba(0,0,0,.25) {
background: $base;
background-image: linear-gradient(45deg,
$accent 25%, transparent 0,
transparent 75%, $accent 0),
linear-gradient(45deg,
$accent 25%, transparent 0,
transparent 75%, $accent 0);
background-position: 0 0, $size $size,
background-size: 2*$size 2*$size;
}
/* Used like... */
@include checkerboard(15px, #58a, tan);
在任何情況下,當(dāng)我們需要這么代碼解決問題的時候,那么使用 SVG 將會更合適。使用 SVG 格子的效果的話,代碼就會變得很簡單:
<svg xmlns="http://www.w3.org/2000/svg"
width="100" height="100" fill-opacity=".25" >
<rect x="50" width="50" height="50" />
<rect y="50" width="50" height="50" />
</svg>
有人可能會質(zhì)疑說:“如果使用 CSS 的話,就可以節(jié)省 HTTP 請求了!”不過,在現(xiàn)代瀏覽器中,我們可以將 SVG 文件嵌入到樣式中,作為一個數(shù)據(jù) URI,我們甚至不需要使用 base64 和 URLencode:
background: #eee url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" \
width="100" height="100"
fill-opacity=".25">\
<rect x="50" width="50" height="50" /> \
<rect y="50" width="50" height="50" /> \
</svg>');
background-size: 30px 30px;
SVG 版本的棋盤格不僅僅是小到了只有 40 個字符,更棒的是減少了重復(fù)性的工作。比如,我們只需修改一處地方,就可以更改顏色,只需修改兩處地方,就可以更改大小。
注意,你可以通過使用反斜線(\
)將 CSS 字符串分解到多行,從而提高可讀性。
可以通過?疊加模式(也被稱為CSS混合模式) 來組合這些技巧,使用?background-blend-mode
?的時候,使用除?normal
?之外的其他屬性值作用到一個或多個圖層,會產(chǎn)生非常有趣的效果,就像是?bennettfeely.com的gradients示例?里所展示的一樣。這些圖案大多只使用了?multiply
?的疊加模式,在此之外overlay
,screen
?或者是?difference
?都非常有用。
上一節(jié)主要介紹了使用CSS3的漸變配合background-size
制作簡單的條紋紋理圖案效果。但實際上,將CSS3的漸變和background-size
配合的好的話,不僅僅可以制作簡單的條紋效果,還可以制作一些復(fù)雜的紋理效果。雖然這些紋理在實際中不十分實用,但讓你練手和熟悉CSS3的強大功能是足以。
更多建議: