CSS Sprites技術早在2005年CSS Zengarden 的園主Dave Shea就在ALA發表對此技術的詳細闡述。
原先只在CSS玩家之間作為一種製作方法流傳,後來出來個14 Rules for Faster-Loading Web Sites,技術人員之間競相傳閱,其中第一條規則Make Fewer HTTP Requests就提到CSS Sprites。於是這個小妖精就火了起來,甚至出現了線上生成工具,勢不可擋也。近來國內很多blog都提到CSS Sprites,最著名的例子莫過於google.co.kr 下方的那幾個動畫。最新發布的YUI中,也是使用到CSS Sprites,幾乎都有的CSS裝飾圖都被一個40×2000的圖包辦。社群大站Facebook最近也使用了一個22×1150的圖片承擔了所有icon。一時間,CSS Sprites無所不在。
CSS Sprites工作原理
我們知道,自CSS革命以降,HTML傾向於語意化,在一般情況下不再在標記裡寫裝飾性的內容而是把呈現的任務交給了CSS。 GUI是繽紛的,少不了各種漂亮的圖來裝飾。新時代的生產方式是,在HTML佈滿各種各樣的鉤子(hook),然後交由CSS來處理。
在需要用到圖片的時候,現階段是透過CSS屬性background-image組合background-repeat, background-position等來實現(題外話:為何我提現階段,因為未來瀏覽器若支援content則又新增另外的實作方法)。我們的主角是,你一定猜到了,就是background-position。透過調整background-position的數值,背景圖片就能以不同的面貌出現在你眼前。其實圖片整體面貌沒有變,由於圖片位置的改變,你看到只該看到的而已。就好比手錶上的日期,你今天看到是21,明天看到是22,是因為它的position往上跳了一格。所以你也大概了解到,CSS Sprites一般只能使用到固定大小的盒子(box)裡,這樣才能夠遮擋住不該看到的部分。
我們使用YUI的sprite.png舉個例子,假如我們有這麼一段程式碼,max代表最大化,min代表最小化,我們需要給它們配上相應的漂亮圖片(這樣我們的網站才能夠吸引人):
最大化 最小化 |
這兩個class都使用同一個圖片:
.min, .max { width:16px; height:16px; background-image:url(sprite.png); background-repeat: no-repeat; /*我們不想讓它平鋪*/ text-indent:-999em; /*隱藏文字的一種方法*/ } |
最大化 最小化 |
我們看到一團灰,沒錯,因為我們還沒有指定background-position,預設為 0 0,可以看下sprite.png,處於這個位置正是灰塊。好了,我們要找出代表最大化的加號和代表最小化的減號的位置找出來。經過測量,最大化按鈕位於Y軸的350px處,最小化按鈕位於Y軸400px處。想想我們如何才能讓它們能夠顯示出來呢,明顯,要向上提升sprite.png,得到程式碼如下:
.max { background-position: 0 -350px;} .min { background-position: 0 -400px;} |
最大化 最小化 |
這次我們成功了!
CSS Sprites優點
我們從前面了解到,CSS Sprites為什麼突然跑火,跟能夠提升網站效能有關。顯而易見,這是它的巨大優點之一。普通製作方式下的大量圖片,現在合併成一個圖片,大大減少了HTTP的連接數。 HTTP連線數對網站的載入效能有重要影響。
CSS Sprites缺點
至於可維護性,這是一般雙刃劍。或許有人喜歡,有人不喜歡,因為每次的圖片改動都得往這張圖片刪除或加入內容,顯得稍微繁瑣。而且算圖片的位置(尤其是這種上千px的圖)也是一件相當不爽的事。當然,在性能的口號下,這些都是可以克服的。
由於圖片的位置需要固定為某個絕對數值,這就失去了諸如center之類的彈性。
前面我們也提到了,必須限制盒子的大小才能使用CSS Sprites,否則可能會出現幹擾圖片的情況。這就是說,在一些需要非單向的平鋪背景和需要網頁縮放的情況下,CSS Sprites並不合適。 YUI的解決方式是,加大圖片之間的距離,這樣可以保持有限的縮放。
CSS Sprites總結
性能壓倒一切。 CSS Sprites是值得推廣的一種技術。尤其適合用於FIR,例如固定大小的icon替換。為保持相容性,圖片中的各個部分保持一定的距離是一種不錯的做法。