CSS3圖案詳解

LeeYao發表於2012-10-28

原文連結:http://24ways.org/2011/css3-patterns-explained

也許你們很多人已經看過了我的《CSS3圖案畫廊》。在過去的一年中它變得非常流行,它向許多網際網路程式設計師展現了CSS3漸變到底有多強大。但是又有多少人真正明白這些圖片是怎樣被創造出來的呢?使用CSS生成的背景最大的好處是——它們可以直接通過樣式表直接修改。但是,如果我們僅僅是拷貝或者貼上我們不理解的CSS程式碼,這些好處將不復存在。我們可以同樣使用資料URI來代替。

重要提示

在下面的所有示例中,為了可讀性和簡潔,我將會直接使用不帶提供商字首的漸變程式碼。但是你需要時刻牢記,由於目前沒有瀏覽器在不使用字首的情況下支援漸變,所以在實際專案中,你需要使用所有的提供商字首(-moz-, -ms-, -o-, -webkit-)。亦或,在需要的時候,你可以使用-prefix-free,在執行時中臨時新增。

所有在這裡描述的語法都是現階段瀏覽器支援的。雖然CSS3的說明文件已經有所改變,但是還沒有瀏覽器對這些改變進行支援。如果你想看看一些新特性,我建議你看以下《dev版說明文件》
如果你還不熟悉CSS漸變,你可以先看看John Allsopp寫的優秀的教程,然後再回來看這篇文章。最後,我假設你已經掌握了CSS漸變的基本知識。

核心思想

我能肯定大多數人可以想象出這段程式碼生成的樣式:

background: linear-gradient(left, white 20%, #8b0 80%);  

正如下圖所看到的一樣,只是簡單的從一個顏色到另外一個顏色的漸變:

enter image description here

線上例項

如你可能知道的一樣,在上面這個例項中,容器寬度的前20%是純白色,而寬度的後20%則是純綠色。而中間的60%則是兩種顏色之間的平滑過渡。讓我們把顏色起止點移動到更接近的位置:

background: linear-gradient(left, white 30%, #8b0 70%);

enter image description here

線上例項

background: linear-gradient(left, white 40%, #8b0 60%);

enter image description here

線上例項

background: linear-gradient(left, white 50%, #8b0 50%);

enter image description here

線上例項

我們注意到顏色之間的漸變越來越收縮,而純色的區域卻在不斷的擴大,直到在最後一個示例中兩種顏色之間再沒有任何的顏色漸變。我們可以通過調整兩種顏色的起止點的位置來使其在某個特定的位置進行顏色改變:

background: linear-gradient(left, white 30%, #8b0 30%);

enter image description here

線上例項

background: linear-gradient(left, white 90%, #8b0 90%);

enter image description here

線上例項

從上面的幾個例子中我們可以學到,當2個顏色的起止點在同一個位置的時候,將不會有顏色漸變,只有純色出現。就算沒有進一步的研究,這種技巧在一些用例中也會非常實用,比如:背景欄、我想要達到我主頁中的效果或者如-prefix-free頁面那樣背景只在一邊顯示,而在另一邊中隱藏起來:

enter image description here

和background-size組合使用

然而,如果我們把漸變和CSS3屬性background-size組合到一起的話,我們將會看到一些神奇的效果:

background: linear-gradient(left, white 50%, #8b0 50%);
background-size: 100px 100px;

enter image description here

線上例項

上圖就是我們剛剛建立的最簡單的圖案:(垂直)條紋。我們可以移除第一個引數(left),並使用top來代替它,我們將會得到水平條紋。好吧,我們承認吧:單純的水平條紋或者垂直條紋實在是有些乏味。我們在網頁中看到的條紋形背景大多是呈斜角的。那麼,就讓我們嘗試下吧。

我們的第一個嘗試就是旋轉漸變角度達到45deg。但是,這個圖案真是醜陋至極:

enter image description here

線上例項

在接下去看之前,我們先思考一下:為什麼我們得不到想要的結果,你能找出其中的緣由麼?

原因就是漸變旋轉角度都是在每一片區塊中進行的,而不是在整個平鋪的背景中進行的。但是,我們在第一次使用圖片去實現斜角條紋背景的時候,不同樣也會出現這樣的問題?然後,我們才知道每種顏色的條紋會被包含兩次,就像下圖這樣:

enter image description here

那麼,讓我們用CSS漸變來實現這樣效果吧。本質上,它和我們前面嘗試過的沒有什麼兩樣,但是需要更多的顏色起止點:

background: linear-gradient(45deg, white 25%,
    #8b0 25%, #8b0 50%, 
    white 50%, white 75%, 
    #8b0 75%);
background-size:100px 100px;

enter image description here

線上例項

我們已經得到了想要的條紋。有一個簡單的方法去記住百分比和顏色的順序,就是,除去開始和最後的顏色,你總是擁有連續的2個相同顏色。

**注意:**Mac下的Firefox,每個圖案的最後,除去2個顏色起止點外,還需要一個額外的100%位置的顏色起止點,如:..., white 75%, #8b0 75%, #8b0 ) 。這個bug在2011年2月被發現,你可以去Bugzilla去為它投票並跟蹤進度

不幸的是,這只是一個hack,當我們改變漸變角度至60deg時,我們就會發現:

enter image description here

線上例項

這種問題到底可不可以解決?還好,CSS3還為我們提供了另一種定義背景的方法,它不僅有助於解決這個問題,而且會讓程式碼更加簡潔明瞭:

background: repeating-linear-gradient(60deg, white, white 35px, #8b0 35px, #8b0 70px);

enter image description here

線上例項

然而,在這個示例中,既然漸變被預設為覆蓋整個容易,背景的大小必須在顏色起止點的位置定義,而不是通過background-size定義。你可能注意到宣告的大小不同於前面指定的方式。這是因為條紋的尺寸使用不同的方式去測量:在第一個示例中,我們指定每一片區塊的大小;在第二個示例中,則是指定的斜條紋的寬度(35px)。

多背景

當只使用單一的漸變的時候你可以建立出條紋圖案。你還可以使用單一的(線性或者徑向)漸變創造出更多的圖案,但它們或多或少有些單調和醜陋。幾乎我畫廊裡所有的圖案都包含了好幾種不同的背景。例如,讓我們建立一個圓點花樣的圖案:

background: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, black 10%) 50px 50px;
background-size:100px 100px;

enter image description here

線上例項

我們注意到這兩個漸變是幾乎一樣的影像,但是被放置到不同的地方來建立圓點花樣的效果。而兩者之間的唯一不同之處就是第一個(最頂層)漸變使用透明背景來替代黑色背景。但是這幅圖案沒有透明區域,它看起來就像使用了一個漸變,因為最上層的漸變會遮蓋住它下面所有的圖層。

這個背景還存在一個問題,你能找出來麼?

這個背景在支援CSS漸變的瀏覽器中會執行良好,但是,一旦執行在不支援漸變的瀏覽器中,圖案將會變成透明,因為所有的樣式宣告都會被忽略掉。我們有兩種方式來補救,每種都對應不同的應用場景。我們要麼在漸變前面先宣告另外一種背景,如下面所示:

background: black;
background: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, black 10%) 50px 50px;
background-size:100px 100px;

要麼,每一種背景屬性都分開來宣告:

background-color: black;
background-image: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, transparent 10%);
background-size:100px 100px;
background-position: 0 0, 50px 50px;

細心的讀者已經注意到我們在最後一個示例中對程式碼做的另外一個修改:我們修改了第二個漸變,讓它擁有了透明背景。這種方法中background-color有2個作用:既是一種顏色補救,又是圓點花樣圖案的背景顏色。這樣,一旦我們想修改背景顏色,只需要一次操作即可。我們要永遠為程式碼的可擴充套件性而努力。你也許會想,圖案永遠不會發生那樣的改變,但,絕大多數情況下,只要有足夠的時間,都會證明你的想法是錯誤的。

我們可以把同樣的技術應用到線性漸變中,進而從直角三角形中建立出棋盤格圖案:

background-color: white;
background-image: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%), 
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%);
background-size:100px 100px;
background-position: 0 0, 50px 50px;

enter image description here

線上例項

使用正確的單位

不要不假思索就使用畫素定義大小,有些情況下,使用em定義大小更有效。例如,你想製作一個帶線條的紙質背景,你想要線條和文字保持一致。如果你使用畫素,你每改一次font-size就必須改一次線條的大小。如果你使用em設定background-size,它就會自然地和文字保持一致。你只需要在更改line-height的時候修改它就行了。

一切皆有可能?

下列這些形狀可能只通過漸變實現麼?

  • 條紋
  • 直角三角形
  • 圓形和橢圓形
  • 半圓形和其他一些通過水平或垂直切割橢圓得到的形狀

你可以通過組合這些形狀來生成正方形或長方形(兩個直角三角形拼湊在一起)、菱形和平行四邊形(4個直角三角形組合到一起)、由部分橢圓形組合而成的曲線和一些其他的形狀。

不為也,非不能也

技術上,可以通過上面這些技術手段創造出任何東西。但是,並不是所有地圖案都是合適的,這種技術的優勢包括:

  • 沒有額外地HTTP請求
  • 簡短的程式碼
  • 易讀的程式碼(不像資料uri),甚至可以在沒有留下CSS檔案的情況下修改程式碼。

複雜的圖案需要大量的漸變來實現,既然他們已經沒有了這種技術幾乎所有的優勢,可能就不比SVG或者點陣圖要好:

  • 它們不再簡短
  • 它們不再易於理解——修改它們需要比使用影像編輯器花更多的精力。

但是它們仍然能夠節省一個http請求,但資料URI同樣能做到這一點。

我已經在我地畫廊中囊括了一些非常複雜的圖案(格子呢圖案馬德拉斯棉布圖案心形圖案太極陰陽圖五角星浪花圖案),儘管我認為在產品中最好不要用到它們(除非是在特殊形況下才使用)。理解它們怎麼工作和編寫這些程式碼能夠幫助大家更深入地理解這門技術。

還有一個小經驗就是如果你的圖案需要一個形狀去掩蓋另外一個形狀地一部分,像五角星形或者太極陰陽圖,那麼你最好還是不要使用它。在這些圖案中,一旦改變背景顏色,你就需要改變這些圖形的顏色,編輯過程會很乏味的哦。

若果某個特定的圖案不能用可以接受的程式碼量來完成的話,並不意味著你必須使用點陣圖。SVG則是一個非常好的替代方案並且已經被所有現代瀏覽器支援。

瀏覽器支援概況

Firefox 3.6+, Chrome 10+,,Safari 5.1+ 和 Opera 11.60+ 都支援CSS漸變(Opera從11.10開始支援線性漸變),馬上到來的IE10中也將會支援漸變。 如果你需要讀取漸變屬性的話,你可以在老的WebKit版本中(包括絕大部分手機瀏覽器)通過-webkit-gradient()方法讀取到漸變資料。

後記

我希望這些技術能對你自己的設計有所幫助。如果你設計出一個和已有的完全不同的圖案,特別是它能展現出一個非常酷的技術,希望能傳送pull request到我們github的圖案畫廊專案中, 同時,我也十分希望我的技術能被運用到實際專案中,所以如果你做出一個很酷的設計或者使用了我的CSS圖案,我將會很樂意去了解它。

節日快樂!


譯者注:

  • 這是我的第一篇翻譯,翻譯功底尚淺,如翻譯有誤,歡迎各位指正。
  • 最近忙於畢設開題,時間倉促,還望見諒。

相關文章