本文原文連接:https://devework.com/postcss-...,轉載請註明原始來源,謝謝!javascript
postcss-lazysprite 是一個基於PostCSS 開發的用於生成雪碧圖圖片及其CSS 的插件,通過半年持續迭代,現已穩定用在微信旗下兩款產品的Web 業務中。其與市面上的雪碧圖插件不一樣在於生成雪碧圖的「懶惰」姿式。css
前端界,伴隨着雪碧圖這個概念出現,自動化工具產生雪碧圖這類工具就層出不窮。不管是早期GUI 工具,仍是如今流行的配合Gulp/Grunt/Webpack 這類構建工具而產生的雪碧圖插件。總之是百花齊放,長江後浪推前浪。html
根據輸入方式的不一樣,如今市面上基於Node.js 的雪碧圖構建工具通常可分爲以下兩種(若有不實,望予以指出):前端
一種是如今國外常見的基於spritesmith 的各種經過構建工具註冊任務進行合併產生雪碧圖的插件,如gulp-sprite、css-sprite、sprity 等。java
// 本段代碼來自sprity 的sample gulp.task('sprites', function () { return sprity.src({ src: './src/images/**/*.{png,jpg}', style: './sprite.css', processor: 'sass', }) .pipe(gulpif('*.png', gulp.dest('./dist/img/'), gulp.dest('./dist/css/'))) });
另外一種是國內以cssgaga、gulp-tmtsprite 爲表明的,在開發階段是寫單個小圖的CSS 樣式,而後也是經過構建工具的註冊任務進行合併產生雪碧圖的插件。git
// 本段代碼來自gulp-tmtsprite 的sample // Input .icon-test { width: 32px; height: 32px; background-image: url(../slice/test.png); } // Output .icon-test { background-image: url(../sprite/style-index.png); } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-webkit-min-device-pixel-ratio: 2.5), only screen and (min-resolution: 240dpi) { .icon-test { background-image:url("../sprite/style-index@2x.png"); background-position: -36px -66px; background-size: 32px; } }
各種工具自己有其合理存在的理由與最適合的使用場景,去褒貶來陪襯我這個插件並非本文的目的。如上面介紹的兩種類型的插件,一種是將雪碧圖合成從常規的寫CSS 行爲中抽離出來,一種是後編譯的雪碧圖合成,其使用場景各不相同。本文介紹的postcss-lazysprite,在於解決的場景是:我想在開發階段就生成雪碧圖並用上其CSS,同時我又想很方便地產生,用起來越簡單越好。所謂lazysprite,就是期許一種「懶惰」的方式去生成雪碧圖。github
postcss-lazysprite 用起來就是那麼簡單,通過配置後,你只須要這樣寫:web
/* ./src/css/index.css */ @lazysprite "filetype";
輸出的天然是完整的雪碧圖以及相應CSS:npm
/* ./dist/css/index.css */ .icon-filetype-doc { background-image: url(../sprites/filetype.3f1f178013.png); background-position: 0 0; width: 80px; height: 80px; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio:2), only screen and (-o-min-device-pixel-ratio:2/1), only screen and (min-device-pixel-ratio:2), only screen and (min-resolution:2dppx), only screen and (min-resolution:192dpi) { .icon-filetype-doc { background-image: url(../sprites/filetype@2x.cbed5ca6a9.png); background-position: 0 0; background-size: 170px 170px; } }
假設後面要新增圖片到filetype 文件夾,那麼直接丟進去就能自動從新合併並更新CSS;若是要新建一個與filetype 同級的文件夾(如logos),那麼在須要的位置@lazysprite "logos";
便可。一切就是那麼簡單,所謂lazy,便是如此。gulp
若是你有用過Sass 框架Compass 的話,你會以爲跟Compass 的雪碧圖產生方式是如此相似。是的,這個插件就是沿用了Compass 的雪碧圖思路,甚至這個插件的的底層就是spritesmith 驅動的,而我在寫這個插件的時候參考了postcss-sprite 的寫法——整個插件實際上是在前端開源環境下,結合自身的需求而來的產物。
可能有讀者看到這裏還不是很清楚postcss-sprite 的運做方式。這裏以Gulp 構建流爲例,講述下其運做方式。
假設你的項目目錄以下:
. ├── gulpfile.js ├── dist └── src ├── css │ └── index.css ├── html │ └── index.html └── slice └── filetype ├── doc.png ├── doc@2x.png ├── pdf.png └── pdf@2x.png
src
是放編譯前的CSS(如今通常是Sass 或Less 的源文件)以及雪碧圖源圖(即單個小圖);dist
則是編譯後 CSS 及產生的雪碧圖圖片及其CSS。
而後在gulpfile.js
配置以下:
var gulp = require('gulp'); var postcss = require('gulp-postcss'); var lazysprite = require('postcss-lazysprite'); gulp.task('css', function () { return gulp.src('./src/css/**/*.css') .pipe(postcss([lazysprite({ imagePath:'./src/slice', stylesheetInput: './src/css', stylesheetRelative: './dist/css', spritePath: './dist/slice', smartUpdate: true, nameSpace: 'icon-' })])) .pipe(gulp.dest('./test/dist/css')); });
上面的每一個option 解釋下:
imagePath
:雪碧圖小圖所在目錄;stylesheetInput
:CSS 文件所在的目錄,通常與gulp.src
的路徑相關;stylesheetRelative
:爲了在生成的CSS 中構造相對路徑而引入,通常與gulp.dest
的路徑相關;spritePath
:生成的雪碧圖放置的目錄;smartUpdate
: 是否啓用智能更新機制,關於smartUpdate,請見下一章節的介紹。nameSpace
:CSS 的命名空間。
注意下你的gulp css
任務通常是gulp.watch
以及默認任務的一部分。
而後你在src/css/index.css
裏面寫下這段話:
@lazysprite "filetype";
輸出內容見上一章節相同部分,就不重複了。
filetype
便是在spritePath: './dist/slice'
定義的目錄下的子目錄,這個目錄下的全部雪碧圖小圖會合成爲一張雪碧圖,圖片名稱默認是以filetype.png
命名。
同時filetype
也會做爲生成的小圖對應CSS class 的一部分。CSS class 的構成便是「命名空間+目錄名+小圖片名」。如doc.png
生成的對應類名爲.icon-filetype-doc
——而後你在HTML 中引入CSS 文件,經過<i class="icon-filetype-doc"></i>
用便可。
postcss-lazysprite 雖然是站在巨人的肩膀上的產物,但其仍是有很多亮點值得一說。
支持 Retina 不是什麼新鮮事,但postcss-lazysprite 支持@2x, @3x, _2x, _3x
這四種後綴的 Retina 圖片,並且'@'與'_'的命名徹底能夠混用。
檢測到非標準 Retina 圖片會予以提示,如@2x 圖片非偶數尺寸的時候。
支持Source Map,這個很少說,之因此是基於 Postcss 開發,就是爲了能支持Source Map。
支持:hover、:active
這類場景,即一些如鼠標 hover 上去須要變logo 的場景。
採用緩存方式以及SmartUpdate 以提高運行時候的性能。如本文開頭所言,postcss-lazysprite 目標是開發階段就能用上雪碧圖,因此緩存機制很重要,總不能在開發階段每保存一次 CSS 就從新走一遍「遍歷全部圖片並生成雪碧圖」的流程。因此只要在開發階段沒有動過圖片或修改@lazysprite 的代碼,除開發階段第一次啓動 Gulp 任務的時候,其它時間均不會重複運行相關流程。另外在配置了SmartUpdate後,會將生成的圖片文件名加入 hash,這樣下一次啓動 Gulp 任務的時候,只要源圖片沒有變化,也不會重複雪碧圖流程。
npm 安裝:
npm i postcss-lazysprite -S
插件自己擁有近十個 opiton 方便用戶根據實際需求自定義相關細節,請參考 README 。
postcss-lazysprite 託管到 Github 上:https://github.com/Jeff2Ma/postcss-lazysprite,歡迎前往提 issues 或參與開發。固然,歡迎先送個star ~
相關文章:
PostCSS 插件postcss-lazyimagecss:自動填寫width / height 屬性
本文原文連接:https://devework.com/postcss-...,轉載請註明原始來源,謝謝!