﻿# 使用 CSS Sprites 設計網頁但不用 background-image 的技巧

使用 [CSS Sprites](http://www.alistapart.com/articles/sprites/) 技巧可以有效減少 HTTP Request 的數量並且加速網頁載入與顯示的速度。簡單的來說，CSS Sprites 就是將頁面中會用到的背景圖檔全部集中放在一個圖片檔中，並利用 CSS 的 background-image 與 background-position 屬性將欲顯示的背景圖部分露出，對瀏覽器來說，如果整頁的背景圖原本有 30 張就會有 30 個 HTTP Request，但全部合在一張圖片後就只需要一個 HTTP Request 而已，還可以透過 [HTTP Cache](http://www.mnot.net/cache_docs/) 技巧將圖片快取在瀏覽器中。

我們在之前也曾經實驗過採用 CSS Sprites 技巧在網站專案中，不過卻遇到一些討厭的問題：

-   若圖片採用 PNG 格式且有用漸層或透明背景的效果的話，在 IE6 會看不到。通常我們會用 [IE6 PNG fix](http://www.twinhelix.com/css/iepngfix/) 解決此問題，不過 [IE6 PNG fix](http://www.twinhelix.com/css/iepngfix/) 與 [CSS Sprites](http://www.alistapart.com/articles/sprites/) 技巧不相容！(因為 background-image 與 background-position 的關係)
-   若將 [CSS Sprites](http://www.alistapart.com/articles/sprites/) 技巧套用在網站主選單中，使用者在列印網頁時可能會看不到背景圖，除非他在**網際網路選項**中有勾選「列印背景的色彩及影像」（預設沒有勾選）。  
    ![網際網路選項中有勾選「列印背景的色彩及影像」](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/fdacb1fbb0264b624cf5-image_3.png "網際網路選項中有勾選「列印背景的色彩及影像」")
-   套用在主選單還有另一個問題，就是原本應該出現圖片的卻改用「背景圖」處理，雖然我們後來是加入一個「看不見的」超連結替代，不過這種寫法實在有點髒。

最近在 [Jennifer Semter 的部落格](http://www.jennifersemtner.com/)看到一則 [extending css spriting](https://web.archive.org/web/20160305051148/http://www.jennifersemtner.com/css/101/extending-css-spriting/) 文章，他不再用 background-image 與 background-position 的技巧，改用標準的 DIV/A 標籤加上 img 標籤與 CSS 的絕對定址與 clip 屬性，直接裁切原本的大圖，將大圖中的一部份切出來顯示在畫面上，一樣是 CSS Sprites 的技巧，但用另一種更好的方法來實做而已。

套用此法的 HTML 如下（摘錄自 [extending css spriting](https://web.archive.org/web/20160305051148/http://www.jennifersemtner.com/css/101/extending-css-spriting/) 文章）：

```
<div class="menu-about">
    <img class="transparent_png" 
         src="http://www.jennifersemtner.com/wp-content/uploads/2008/12/company-menu.png" 
         alt="About" title="About Us" width="611" height="39" />
</div>
```

套用的 CSS 欲法如下：

```
.menu-about { 
    position: relative;
    top: 0; left: -293px;
    width: 106px; height: 29px; 
}
.menu-about img {
    position: absolute; 
    clip: rect(0 399px 29px 293px);
}
```

我覺得這方法的確比較符合實務的情境，不但能跨瀏覽器，列印的問題也解決了，HTML 也比較乾淨，但對於設計師來說可能會加重一些負擔，因為在設計的時候要去計算 position 的位址與圖片裁切的座標。我認識許多設計師，大多數設計師數學好像不太好，對於太邏輯的東西也有點排斥，要它們學習 CSS Sprites 的設計方式，可能會需要好好溝通教育一番。

**相關連結**

-   [extending css spriting](https://web.archive.org/web/20160305051148/http://www.jennifersemtner.com/css/101/extending-css-spriting/)
-   [Best Practices for Speeding Up Your Web Site](http://developer.yahoo.com/performance/rules.html) @ Yahoo
-   [IE PNG Fix v1.0 / 2.0 Alpha 3](http://www.twinhelix.com/css/iepngfix/)
-   [Caching Tutorial for Web Authors and Webmasters](http://www.mnot.net/cache_docs/)
-   [加速前端網頁效能的14條規則](/post/2007/11/24/14-rules-for-faster-front-end-performance-notes)
