淺談 CSS Sprites 雪碧圖應用
圖標字體是個比較大的技術討論點, 關於它可以出好幾篇博文,可惜本文主角不是它, 今天主要探討下 CSS Sprite -- 雪碧圖 的各種實現。
CSS 雪碧圖簡介
開始說雪碧圖各種實現前, 簡單說下什麼是雪碧圖?雪碧圖的原理是什麼?
什麼是雪碧圖?
雪碧圖也叫CSS精靈, 是一CSS圖像合成技術;
上面解釋說它是一項技術,但我們開發人員往往將小圖標 合併在一起之後的圖片稱作雪碧圖;術語定義其實不用糾結, 我們知道它主要用在小圖標顯示上就行了。
CSS 雪碧圖應用原理:
只有一張大的合併圖, 每個小圖標節點如何顯示單獨的小圖標呢?其實就是 截取 大圖一部分顯示,而這部分就是一個小圖標,如下圖:
如顯示上面 QQ 小圖標, 則在合併圖中X軸向右60像素, Y軸0像素, 截取寬高均為48像素;則 這個小圖標就出來了:關鍵樣式:
background-image: url("sprite.png");nbackground-position: -60px 0px;nwidth:48px;nheight:48px;n
接下來, 就開始進入實踐環節, 如果我們要實現如下效果, 該怎麼做呢?
按正常開發流程, 我們的設計部同事會給我們這樣的一個設計稿(實際設計稿會有更多無關圖層):
然後就是前端作為切圖仔表現的時候了, 簡單說下切圖步驟(高級切圖仔請跳過):1.裁剪工具(快捷鍵C), 選中 切片工具:
2.選中要導出的圖標(建議快鍵鍵z用縮放工具放大然後選切圖區):需要說下的, 新版本 photoshop 從2015 CC開始就不用這麼麻煩去切圖了, 直接選中小圖標圖層右鍵「快速導出為PNG」, 即可得到對應小圖標的png文件;
Photoshop軟體版本不夠新怎麼辦? 你可以看看 21款強大高效的Photoshop擴展插件第10個Breezy 即為切圖插件;快速導出 或 切圖 成功後, 就有了以下四個小圖標了:小圖標素材整理好後, 接下里就是針對上述頁面效果的各種實現以及對比了。傳統網頁調用小圖標(原始方式)
首先說下雪碧圖技術沒推廣開來 或 新手小白開發以上效果時, 是這樣實現的:
demo地址:
小圖標調用Demo(原始版)
代碼地址:
小圖標調用源碼(原始版)
分別為四個小圖標定義不同的四張小圖標, 關鍵樣式代碼:
.ps_demo_wrap .demo_icon{ntposition: relative;ntfloat:left;ntmargin:13px 0px 0px 10px;ntcursor: pointer;ntwidth:54px;ntheight:54px;n}n.ps_demo_wrap .weibo_icon{ background-image:url("../scss/images/icon_weibo.png"); }n.ps_demo_wrap .qq_icon{ background-image:url("../scss/images/icon_qq.png"); }n.ps_demo_wrap .douban_icon{ background-image:url("../scss/images/icon_douban.png"); }n.ps_demo_wrap .renren_icon{ background-image:url("../scss/images/icon_renren.png"); }n
不使用雪碧圖, 單純調用小圖片有以下優缺點:
優點:調用簡單、維護方便;n
缺點:請求文件過多、引發性能問題;為什麼不建議使用該方式顯示小圖標?
每個小圖標都單獨調用一圖片, 即意味著每個小圖標的顯示都產生一個HTTP請求;學習過HTTP相關知識應該知道,一般情況下每次創建一 HTTP請求,請求到的內容 往往是次要的(除非文件特別大), 性能開銷主要在請求、以及響應階段;使用以上方式實現如 鬥魚直播間雪碧圖或以下知乎的雪碧圖, 造成的性能消耗肯定不小!
綜上所述, 網站開發中遇到小圖標顯示, 優先考慮雪碧圖實現; 那麼問題來了, 小圖標合併成一張圖片,如果需求有改動導致雪碧圖修改(新增或修改小圖標), 更糟糕的是多個開發人員的功能模塊都得調用該雪碧圖(意味著多人會修改到雪碧圖), 該如何開發、維護雪碧圖呢?
雪碧圖實現1: CSS Gaga
慕課網雪碧圖教程推薦軟體,CssGaga 幫助索引PS: 該軟體只有windows版本, 並未找到mac版;CssGaga如何實現雪碧圖呢?
1.下載安裝該軟體;
2.選中「圖片合成」菜單後, 將小圖標拖入軟體首頁即可生成對應的雪碧圖以及CSS Sprite代碼;
3.根據上述生成的雪碧圖以及對應圖標位置,編寫CSS;.ps_demo_wrap .weibo_icon,n.ps_demo_wrap .qq_icon,n.ps_demo_wrap .douban_icon,n.ps_demo_wrap .renren_icon{n width:54px;n height:54px;n background:url("../images/CssGaga.png");n}n.ps_demo_wrap .weibo_icon{ background-position: -168px 0px; }n.ps_demo_wrap .qq_icon{ background-position: -56px 0px; }n.ps_demo_wrap .douban_icon{ background-position: 0px 0px; }n.ps_demo_wrap .renren_icon{ background-position: -112px 0px; }n
demo地址:
雪碧圖實現1Demo
代碼地址:
雪碧圖實現1源碼
實現方案1問題比較多:
1.只支持windows操作系統, 對於很多mac開發的人而言不友好;
2.多人維護雪碧圖時,溝通成本較高(得確認新的雪碧圖中舊小圖標位置是否有變化);
接下來分析的實現方案2普及率比較高, 應該是目前大部分前端組的實現方式;雪碧圖實現2:photoShop
雖然我們不是設計人員,但作為傳統web開發人員photoShop幾乎是必學技能; 當然隨著前端技術的不斷發展, 前端開發人員使用photoShop的幾率會越來越少;
回歸正題, 雪碧圖的實現方案2就是使用photoShop來生成雪碧圖, 並且雪碧圖以PSD文件格式保留, 後續修改圖標(或新增圖標)只需要找到並修改該PSD即可, 再也不用保存原來的小圖標了~
實現步驟:
1.下載(mac 版、windows版)PS軟體;
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:gulpn
如果讀者從未聽說gulp或者對gulp了解的比較少, 建議網上搜索並閱讀gulp相關資料後繼續觀看以下內容!
gulp環境搭建無非就是 安裝nodejs 然後通過npm(建議使用cnpm)安裝gulp模塊;
具體可參考:前端構建工具gulp的使用;
使用gulp自動生成雪碧圖有兩種實現方式
gulp生成 css 代碼實現步驟:
1.安裝 gulp 開發雪碧圖的依賴模塊,具體要哪些模塊可參考本demo的配置文件;
PS: 為什麼不直接參考本demo的package.json文件?因為本demo所在工程引用的其他nodejs模塊較多容易造成干擾。
2.編寫配置文件, 以下是關鍵配置代碼:
/*n* 雪碧圖合併task( 輸出到 css文件 )n* 參數1:執行目錄;n* 參數2:生成的sass和圖片的文件名;n* example:gulp sprite-css --scss --index_css_gulpn*/ngulp.task(sprite-css, function(){n var DEST_NAME = args[1];n return gulp.src(`${WATCH_SRC}/**/*.png`)n .pipe(spritesmith({n imgName: DEST_NAME + .png,n cssName: DEST_NAME + .css,n imgPath: ../images/ + DEST_NAME + .pngn }))n .pipe(gulpif(*.png, gulp.dest(images/)))n .pipe(gulpif(*.css, gulp.dest(css/)));n});n
之所以推薦gulp, 是因為gulp非常的靈活, 看懂gulp模塊的API可以根據你的項目情況編寫對應的配置文件。所以以上配置文件只是一個參考, 實現的功能幾乎不可能遷移到其他項目。
3.編寫好配置文件後, cmd(windows)或終端(mac)到配置文件同級目錄(gulpfile.js, gulp規定配置文件名字必須為gulpfile)然後執行指令:
gulp sprite-css --scss --index_css_gulpn
就會在指定路徑生成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可以明顯提高編寫樣式的效率)
實現步驟:
1、2、3步驟同上, 只是第三步驟指定的指令為:
gulp sprite --scss --mySpriten
關鍵配置代碼:
/*n* 雪碧圖合併task( 輸出到 scss文件)n* 參數1:執行目錄;n* 參數2:生成的sass和圖片的文件名;n* 參數3:輸出目錄(非必填),不填的話輸出目錄為執行目錄n* example:gulp sprite --scss --mySpriten*/ngulp.task(sprite, function(){n var DEST_SRC = args[2] !== undefined ? args[2] : args[0];n var DEST_NAME = args[1];n var spriteData = gulp.src(`${WATCH_SRC}/**/*.png`).pipe(spritesmith({n imgName: DEST_NAME + .png,n imgPath: ../images/ + DEST_NAME + .png,n cssName: _ + DEST_NAME + .scssn }));nn var imgStream = spriteData.imgn .pipe(buffer())n .pipe($.imagemin())n .pipe(gulp.dest(images));nn var cssStream = spriteData.cssn .pipe(gulp.dest(`${DEST_SRC}`));nn return merge(imgStream, cssStream);n});n
執行完指令後會在對應目錄生成_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);nvar SpritesmithPlugin = require(webpack-spritesmith);nnmodule.exports = {n entry: path.resolve(__dirname, app/main.js),n output: {n path: path.resolve(__dirname, build),n filename: bundle.js,n },n plugins: [n new SpritesmithPlugin({n src: {n cwd: path.resolve(__dirname, app/images/),n glob: *.pngn },n target: {n image: path.resolve(__dirname, build/images/sprite.png),n css: path.resolve(__dirname, build/css/sprite.css)n },n apiOptions: {n cssImageRef: ../images/sprite.pngn },n spritesmithOptions: {n algorithm: top-downn }n })n ]n};n
4.在配置文件同級目錄下,執行指令:
webpackn
同實現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%;nbackground-color: rgba(0,0,0,.5);n
rgba顏色方面倒是可以使用透明+濾鏡(低版本瀏覽器)實現, 圓角就只有新增圖標了, 當然以上只是demo不用在意其他細節了哈~
參考資料:
CSS Sprite實踐應用-慕課網
Photoshop實踐分享PPT
HTTP協議詳解
21款強大高效的Photoshop擴展插件
CssGaga 幫助索引
前端構建工具gulp的使用
十分鐘學會sass
webpack中文指南
推薦閱讀:
※一道滴滴的負載均衡前端面試題
※2018 前端性能優化清單 —— 第一部分
※前端瀏覽器緩存及代碼部署
※有哪些比較好 CSS 簡寫(壓縮)工具?