網站開發90%會用到小圖標, 多小圖標調用顯示是前端開發常見的問題;目前小圖標顯示常見有兩種方式(其餘方式歡迎補充):
1.圖標字體 顯示;如小米官網左側菜單欄:javascript
2.CSS Sprite(CSS 精靈), 也稱做 雪碧圖;如華爲官網右側提示欄:css
圖標字體是個比較大的技術討論點, 關於它能夠出好幾篇博文,惋惜本文主角不是它, 今天主要探討下 CSS Sprite -- 雪碧圖 的各類實現。html
開始說雪碧圖各類實現前, 簡單說下什麼是雪碧圖?雪碧圖的原理是什麼?
什麼是雪碧圖?前端
雪碧圖也叫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請求,請求到的內容 每每是次要的(除非文件特別大), 性能開銷主要在請求、以及響應階段;使用以上方式實現如 鬥魚直播間雪碧圖或如下知乎的雪碧圖, 形成的性能消耗確定不小!
綜上所述, 網站開發中遇到小圖標顯示, 優先考慮雪碧圖實現; 那麼問題來了, 小圖標合併成一張圖片,若是需求有改動致使雪碧圖修改(新增或修改小圖標), 更糟糕的是多個開發人員的功能模塊都得調用該雪碧圖(意味着多人會修改到雪碧圖), 該如何開發、維護雪碧圖呢?
慕課網雪碧圖教程推薦軟件,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普及率比較高, 應該是目前大部分前端組的實現方式;
雖然咱們不是設計人員,但做爲傳統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生成雪碧圖,也是本文推薦的雪碧圖實現方式!
若是讀者從未據說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 都是大部分前端組要求掌握的技能;
說到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中文指南