淺談 CSS Sprites 雪碧圖應用

圖片描述

前言

網站開發90%會用到小圖標, 多小圖標調用顯示是前端開發常見的問題;目前小圖標顯示常見有兩種方式(其餘方式歡迎補充):
1.圖標字體 顯示;如小米官網左側菜單欄:
圖片描述javascript

2.CSS Sprite(CSS 精靈), 也稱做 雪碧圖;如華爲官網右側提示欄:
圖片描述css

圖標字體是個比較大的技術討論點, 關於它能夠出好幾篇博文,惋惜本文主角不是它, 今天主要探討下 CSS Sprite -- 雪碧圖 的各類實現。html

CSS 雪碧圖簡介

開始說雪碧圖各類實現前, 簡單說下什麼是雪碧圖?雪碧圖的原理是什麼?
什麼是雪碧圖?前端

雪碧圖也叫CSS精靈, 是一CSS圖像合成技術;java

上面解釋說它是一項技術,但咱們開發人員每每將小圖標 合併在一塊兒以後的圖片稱做雪碧圖;術語定義其實不用糾結, 咱們知道它主要用在小圖標顯示上就好了。node

CSS 雪碧圖應用原理:webpack

只有一張大的合併圖, 每一個小圖標節點如何顯示單獨的小圖標呢?
其實就是 截取 大圖一部分顯示,而這部分就是一個小圖標,以下圖:git

圖片描述

如顯示上面 QQ 小圖標, 則在合併圖中X軸向右60像素, Y軸0像素, 截取寬高均爲48像素;則 這個小圖標就出來了:github

圖片描述

關鍵樣式:web

background-image: url("sprite.png");
background-position: -60px 0px;
width:48px;
height:48px;

接下來, 就開始進入實踐環節, 若是咱們要實現以下效果, 該怎麼作呢?

圖片描述
圖片描述

按正常開發流程, 咱們的設計部同事會給咱們這樣的一個設計稿(實際設計稿會有更多無關圖層):
圖片描述

而後就是前端做爲切圖仔表現的時候了, 簡單說下切圖步驟(高級切圖仔請跳過):
1.裁剪工具(快捷鍵C), 選中 切片工具:

圖片描述

2.選中要導出的圖標(建議快鍵鍵z用縮放工具放大而後選切圖區):
圖片描述
圖片描述

3.導出爲web格式圖片快捷鍵:Alt+Shift+Ctrl+S(mac: Alt+Shift+Commond+S)

圖片描述
圖片描述

須要說下的, 新版本 photoshop 從2015 CC開始就不用這麼麻煩去切圖了, 直接選中小圖標圖層右鍵「快速導出爲PNG」, 便可獲得對應小圖標的png文件;

圖片描述

Photoshop軟件版本不夠新怎麼辦? 你能夠看看 21款強大高效的Photoshop擴展插件
第10個Breezy 即爲切圖插件;快速導出 或 切圖 成功後, 就有了如下四個小圖標了:

圖片描述

小圖標素材整理好後, 接下里就是針對上述頁面效果的各類實現以及對比了。

傳統網頁調用小圖標(原始方式)

首先說下雪碧圖技術沒推廣開來 或 新手小白開發以上效果時, 是這樣實現的:demo地址:
小圖標調用Demo(原始版)
代碼地址:
小圖標調用源碼(原始版)
分別爲四個小圖標定義不一樣的四張小圖標, 關鍵樣式代碼:

.ps_demo_wrap .demo_icon{
    position: relative;
    float:left;
    margin:13px 0px 0px 10px;
    cursor: pointer;
    width:54px;
    height:54px;
}
.ps_demo_wrap .weibo_icon{ background-image:url("../scss/images/icon_weibo.png"); }
.ps_demo_wrap .qq_icon{ background-image:url("../scss/images/icon_qq.png"); }
.ps_demo_wrap .douban_icon{ background-image:url("../scss/images/icon_douban.png"); }
.ps_demo_wrap .renren_icon{ background-image:url("../scss/images/icon_renren.png"); }

不使用雪碧圖, 單純調用小圖片有如下優缺點:
優勢:調用簡單、維護方便; 缺點:請求文件過多、引起性能問題;
爲何不建議使用該方式顯示小圖標?
每一個小圖標都單獨調用一圖片, 即意味着每一個小圖標的顯示都產生一個HTTP請求;學習過HTTP相關知識應該知道,通常狀況下每次建立一 HTTP請求,請求到的內容 每每是次要的(除非文件特別大), 性能開銷主要在請求、以及響應階段;使用以上方式實現如 鬥魚直播間雪碧圖或如下知乎的雪碧圖, 形成的性能消耗確定不小!

圖片描述

綜上所述, 網站開發中遇到小圖標顯示, 優先考慮雪碧圖實現; 那麼問題來了, 小圖標合併成一張圖片,若是需求有改動致使雪碧圖修改(新增或修改小圖標), 更糟糕的是多個開發人員的功能模塊都得調用該雪碧圖(意味着多人會修改到雪碧圖), 該如何開發、維護雪碧圖呢?

雪碧圖實現1: CSS Gaga

圖片描述

慕課網雪碧圖教程推薦軟件,CssGaga 幫助索引PS: 該軟件只有windows版本, 並未找到mac版;CssGaga如何實現雪碧圖呢?
1.下載安裝該軟件;
2.選中「圖片合成」菜單後, 將小圖標拖入軟件首頁便可生成對應的雪碧圖以及CSS Sprite代碼;

圖片描述

3.根據上述生成的雪碧圖以及對應圖標位置,編寫CSS;

.ps_demo_wrap .weibo_icon,
.ps_demo_wrap .qq_icon,
.ps_demo_wrap .douban_icon,
.ps_demo_wrap .renren_icon{
  width:54px;
  height:54px;
  background:url("../images/CssGaga.png");
}
.ps_demo_wrap .weibo_icon{ background-position: -168px 0px; }
.ps_demo_wrap .qq_icon{ background-position: -56px 0px; }
.ps_demo_wrap .douban_icon{ background-position: 0px 0px; }
.ps_demo_wrap .renren_icon{ background-position: -112px 0px; }

demo地址:
雪碧圖實現1Demo
代碼地址:
雪碧圖實現1源碼

實現方案1問題比較多:

1.只支持windows操做系統, 對於不少mac開發的人而言不友好;

2.多人維護雪碧圖時,溝通成本較高(得確認新的雪碧圖中舊小圖標位置是否有變化);
接下來分析的實現方案2普及率比較高, 應該是目前大部分前端組的實現方式;

雪碧圖實現2:photoShop

雖然咱們不是設計人員,但做爲傳統web開發人員photoShop幾乎是必學技能; 固然隨着前端技術的不斷髮展, 前端開發人員使用photoShop的概率會愈來愈少;
迴歸正題, 雪碧圖的實現方案2就是使用photoShop來生成雪碧圖, 而且雪碧圖以PSD文件格式保留, 後續修改圖標(或新增圖標)只須要找到並修改該PSD便可, 不再用保存原來的小圖標了~
實現步驟:

圖片描述

2.新建PSD文件根據設計稿肯定初始大小:300*150;

圖片描述

3.複製設計稿圖層;

圖片描述

4.雪碧圖PSD新建參考線;

圖片描述

圖片描述

5.根據參考線肯定小圖標位置;

圖片描述

圖片描述

圖片描述

6.使用裁剪工具裁剪後,PSD導出爲png, 快捷鍵: Alt+Shift+Ctrl+S(mac: Alt+Shift+Commond+S);

圖片描述

7.獲取小圖標大小、位置;
選中圖層, Ctrl+T (mac: Commond + T), 在信息面板查看圖層信息;

圖片描述

8.根據雪碧圖 編寫對應CSS;

圖片描述

以上步驟雖然多 熟悉後其實很快, 但 其對新手而言的確不友好;

demo地址:
雪碧圖實現2Demo
代碼地址:
雪碧圖實現2源碼

實現方案2問題:

1.操做PSD步驟有點多, 須要開發人員熟悉PS操做;

2.PSD文件比較大, 也不太適合保存在項目中, 通常放SVN共享維護;(SVN服務器宕機、PSD文件衝突等也須要很多時間成本)
好了,接下來分析的是實現方式3, 使用自動化部署工具gulp生成雪碧圖,也是本文推薦的雪碧圖實現方式!

雪碧圖實現3:gulp

若是讀者從未據說gulp或者對gulp瞭解的比較少, 建議網上搜索並閱讀gulp相關資料後繼續觀看如下內容!

圖片描述

gulp環境搭建無非就是 安裝nodejs 而後經過npm(建議使用cnpm)安裝gulp模塊;
具體可參考:前端構建工具gulp的使用
使用gulp自動生成雪碧圖有兩種實現方式 gulp生成 css 代碼

實現步驟:

1.安裝 gulp 開發雪碧圖的依賴模塊,具體要哪些模塊可參考本demo的配置文件
PS: 爲何不直接參考本demo的package.json文件?由於本demo所在工程引用的其餘nodejs模塊較多容易形成干擾。

2.編寫配置文件, 如下是關鍵配置代碼:

/*
* 雪碧圖合併task( 輸出到 css文件 )
* 參數1:執行目錄;
* 參數2:生成的sass和圖片的文件名;
* example:gulp sprite-css --scss --index_css_gulp
*/
gulp.task('sprite-css', function(){
  var DEST_NAME = args[1];
  return  gulp.src(`${WATCH_SRC}/**/*.png`)
              .pipe(spritesmith({
                  imgName: DEST_NAME + '.png',
                  cssName: DEST_NAME + '.css',
                  imgPath: '../images/' + DEST_NAME + '.png'
              }))
              .pipe(gulpif('*.png', gulp.dest('images/')))
              .pipe(gulpif('*.css', gulp.dest('css/')));
});

之因此推薦gulp, 是由於gulp很是的靈活, 看懂gulp模塊的API能夠根據你的項目狀況編寫對應的配置文件。因此以上配置文件只是一個參考, 實現的功能幾乎不可能遷移到其餘項目。

3.編寫好配置文件後, cmd(windows)或終端(mac)到配置文件同級目錄(gulpfile.js, gulp規定配置文件名字必須爲gulpfile)而後執行指令:

gulp sprite-css --scss --index_css_gulp

就會在指定路徑生成index_css_gulp.css 以及 index_css_gulp.png, 通常是拷貝index_css_gulp.css樣式後再刪除該css文件, 本demo功能比較簡單, 因此直接在index_css_gulp.css添加新樣式;
demo地址:
雪碧圖實現3_1Demo
代碼地址:
雪碧圖實現3_1源碼

gulp 生成 sass 代碼(推薦)

比起上述用gulp生成css代碼, 本人更推薦使用gulp生成sass代碼,由於你已經安裝了gulp了那順便安裝下gulp-sass很簡單。越是大型的項目, sass 的優點越明顯, 固然小項目用它也不差。(sass能夠明顯提升編寫樣式的效率)

圖片描述

實現步驟

一、二、3步驟同上, 只是第三步驟指定的指令爲:

gulp sprite --scss --mySprite

關鍵配置代碼:

/*
* 雪碧圖合併task( 輸出到 scss文件)
* 參數1:執行目錄;
* 參數2:生成的sass和圖片的文件名;
* 參數3:輸出目錄(非必填),不填的話輸出目錄爲執行目錄
* example:gulp sprite --scss --mySprite
*/
gulp.task('sprite', function(){
    var DEST_SRC = args[2] !== undefined ? args[2] : args[0];
    var DEST_NAME = args[1];
    var spriteData = gulp.src(`${WATCH_SRC}/**/*.png`).pipe(spritesmith({
        imgName: DEST_NAME + '.png',
        imgPath: '../images/' + DEST_NAME + '.png',
        cssName: '_' + DEST_NAME + '.scss'
    }));

    var imgStream = spriteData.img
        .pipe(buffer())
        .pipe($.imagemin())
        .pipe(gulp.dest('images'));

    var cssStream = spriteData.css
        .pipe(gulp.dest(`${DEST_SRC}`));

    return merge(imgStream, cssStream);
});

執行完指令後會在對應目錄生成_mySprite.scss 、mySprite.png, 根據sass語法帶「_」前綴的文件爲調用模塊, 只能被其餘sass文件調用不會被編譯成同名css文件;生成的_mySprite.scss文件手動添加到目標樣式index.scss中調用, 而後經過監聽(配置文件的sass:watch)自動生成index.css文件,配置文件能夠在執行指令的時候指定路徑,因此能適應更多的場景。

demo地址:
雪碧圖實現3_2Demo
代碼地址:
雪碧圖實現3_2源碼

實現方案3問題:
1.gulp 相關知識得熟悉才能寫出對應的配置文件;

2.如使用gulp生成scss文件還得學習sass相關資料

PS: gulp 跟 sass 都是大部分前端組要求掌握的技能;

雪碧圖實現4:webpack

說到webpack不少人會聯想到ReactJs, 的確前段時間 ReactJs 的大熱讓更多的人知道了webpack, 但webpack並非ReactJs內置的模塊, 它是德國人開發出來的模塊加載工具。由於很好用因此被ReactJs做爲推薦加載工具, webpack能夠跟其餘庫一塊兒完成項目,本demo單獨使用webpack完成。

圖片描述

實現步驟

1.配置webpack開發環境(其實也是安裝nodejs環境+cnpm安裝對應模塊而已);

2.安裝雪碧圖依賴模塊:webpack-spritesmith;

3.將素材小圖標放入對應文件夾,編寫配置文件-webpack.config.js:

var path = require('path');
var SpritesmithPlugin = require('webpack-spritesmith');

module.exports = {
    entry: path.resolve(__dirname, 'app/main.js'),
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'bundle.js',
    },
    plugins: [
        new SpritesmithPlugin({
          src: {
            cwd: path.resolve(__dirname, 'app/images/'),
            glob: '*.png'
          },
          target: {
            image: path.resolve(__dirname, 'build/images/sprite.png'),
            css: path.resolve(__dirname, 'build/css/sprite.css')
          },
          apiOptions: {
            cssImageRef: '../images/sprite.png'
          },
          spritesmithOptions: {
            algorithm: 'top-down'
          }
        })
    ]
};

4.在配置文件同級目錄下,執行指令:

webpack

同實現3_1在生成的sprite.css手動添加樣式demo就完成了!該實現方式相似gulp, 都使用「 spritesmith」模塊,都寫配置文件+執行指令生成雪碧圖,固然webpack方式也能夠生成scss文件, 限於本文篇幅就不作介紹了(實際上是還不會[一臉懵逼撓頭])。

demo地址:
雪碧圖實現4Demo
代碼地址:
雪碧圖實現4源碼

實現方案4問題:

1.須要學習webpack相關知識;(如今webpack官網教程完善些了,不像早些時候官網教程外鏈到別人博客,評論區裏各類吐槽表情包~~~)

2.webpack是一套完整的模塊引用工具,不止樣式, 其餘功能不必定用的上。

結語:

除了 gulp 跟 webpack 外,還有國產前端部署的解決方案FIS3, 其對小圖標也有一套部署配置流程, 由於不瞭解就不寫了, 感興趣的同窗能夠去學習下;webpack跟FIS3包含的其餘功能多一些(特別是FIS3可稱爲完整的解決方案),通常項目若是大方向的技術選型沒定webpack或FIS3,就單純完成雪碧圖而言不太推薦;
最後說明下, 上述的demo實現是有瀏覽器兼容問題的, IE8(包括IE8)如下版本不支持圓角和rgba單位值:
border-radius:50%;background-color: rgba(0,0,0,.5);
rgba顏色方面卻是可使用透明+濾鏡(低版本瀏覽器)實現, 圓角就只有新增圖標了, 固然以上只是demo不用在乎其餘細節了哈~


參考資料
CSS Sprite實踐應用-慕課網
Photoshop實踐分享PPT
HTTP協議詳解
21款強大高效的Photoshop擴展插件
CssGaga 幫助索引
前端構建工具gulp的使用
十分鐘學會sass
webpack中文指南

相關文章
相關標籤/搜索