专栏首页DeveWorkpostcss-lazysprite: 一种生成CSS 雪碧图的懒惰姿势

postcss-lazysprite: 一种生成CSS 雪碧图的懒惰姿势

postcss-lazysprite 是一个基于PostCSS 开发的用于生成雪碧图图片及其CSS 的插件,经过半年持续迭代,现已稳定用在旗下两款产品的Web 业务中。其与市面上的雪碧图插件不同在于生成雪碧图的“懒惰”姿势。

前言

前端界,伴随着雪碧图这个概念出现,自动化产生雪碧图这类工具就层出不穷。无论是早期GUI 工具,还是现在流行的配合Gulp/Grunt/Webpack 这类构建工具而产生的雪碧图插件。总之是百花齐放,长江后浪推前浪,后浪死在沙滩上

根据输入方式的不同,现在市面上基于Node.js 的雪碧图构建工具一般可分为如下两种(如有不实,望予以指出):

一种是现在国外常见的基于spritesmith 的各类通过构建工具注册任务进行合并产生雪碧图的插件,如gulp-sprite、css-sprite、sprity 等。

// 本段代码来自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 样式,然后也是通过构建工具的注册任务进行合并产生雪碧图的插件。

// 本段代码来自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,就是期许一种“懒惰”的方式去生成雪碧图。

postcss-lazysprite 用起来就是那么简单,经过配置后,你只需要这样写:

/* ./src/css/index.css */ @lazysprite "filetype";

输出的自然是完整的雪碧图以及相应CSS:

/* ./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,即是如此。

如果你有用过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 ~

相关文章:

从0到1:PostCSS 插件开发最佳实践

PostCSS 插件postcss-lazyimagecss:自动填写width / height 属性

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 为你的WordPress 主题添加结构化数据/丰富文本摘要,高亮搜索结果(上)

    对于SEO ,咱们这些业余人士只能是从技术的角度来驾驭。网站经营的前期需要做好搜索引擎优化,对于WordPress 网站,其实最好的方式是在WordPress ...

    Jeff
  • 【MindiaX实例】 PHP 在foreach 中获取JSON 单个数据

    之前在开发MindiaX 主题的时候,遇到一个要解析远程JSON 文件的数据的问题。当时困扰我的是整型与数字字符串是否等价的问题。现在过年有时间,就记录回来。 ...

    Jeff
  • CSS Auto Reload:解放F5 键,自动刷新浏览器的前端利器(Chrome 扩展)

    在进行前端开发的时候(本文具体而言是编辑CSS 文件时候),常常要做的是刷新浏览器查看修改后的样式。那么最常用到的就是F5 键了,以前在开发WordPress ...

    Jeff
  • 物联网医疗保健:未来医疗行业的发展方向

    由于人口老龄化,昂贵的医疗服务以及过时的医疗基础设施,对物联网医疗保健的需求有所增加。经济实惠和创新的医疗保健是未来的现实。物联网使我们能够从根本上改变这个行业...

    Bessalitskykh
  • Unbounded机器人倒闭:初创公司须知的教训

    Unbounded机器人曾是最有前景的机器人初创公司,近日宣布倒闭。该公司曾因UBR-1服务机器人而声名鹊起,而现在起市场上将再无此产品可售。 IEEE Spe...

    机器人网
  • 只要改变温度,新型机器人就能全速前进

    机器人通常需要供电才能运动,没有电就意味着没有运动,不过,加州理工学院和苏黎世联邦理工学院的工程师已开发出能够在不使用任何电机、伺服系统或电源的情况下自行推进的...

    机器人网
  • 把性爱机器人用作商业用途究竟合不合法?

    在世界上很多国家,性交易属于非法行业,然而,随着人工智能技术的发展以及性爱机器人的出现,这种存在于人类与机器人之间的私密行为却似乎有将性交易合法化的趋势…… 据...

    机器人网
  • iOS自动登录

    只在登录页面进行判断,如果用户是自动登录,那么再跳转到主页面,这种方法实现起来相对简单,但是每次登录都要显示登录页面,不人性化

    剑行者
  • 机器人“四大家族”加码中国市场

    “这个展示中心是目前行业中规模最大的,也与中国工业机器人的市场规模相匹配。”12月17日,安川电机(中国)有限公司董事长兼总经理今福正教在其新机器人中心揭幕时这...

    机器人网
  • 重度发烧友教你,如何成为机器人工程师(硬件篇)

    我是一位机器人重度发烧友。在开篇之前,请容许我先追忆一下往昔。第一次接触机器人是在大一的上学期,我选修了一门课《机器人概论》,这门课可以说是视频赏析课,因为老师...

    机器人网

扫码关注云+社区

领取腾讯云代金券