资讯专栏INFORMATION COLUMN

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

BearyChat / 864人阅读

摘要:无论是早期工具,还是现在流行的配合这类构建工具而产生的雪碧图插件。

本文原文链接:https://devework.com/postcss-...,转载请注明原始来源,谢谢!

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 文件,通过用即可。

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 属性

本文原文链接:https://devework.com/postcss-...,转载请注明原始来源,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/112151.html

相关文章

  • 2017-06-18 前端日报

    摘要:前端日报精选精读高阶组件知乎专栏是如何重新定义前端开发的知乎专栏为您的性能选择最佳的引擎知乎专栏中的尺寸单位掘金一种生成雪碧图的懒惰姿势中文第期编写现代代码周刊第期的平凡之路我们到底可以通过多少种方式修改元素样式掘金 2017-06-18 前端日报 精选 精读 React 高阶组件 - 知乎专栏React 是如何重新定义前端开发的 - 知乎专栏为您的 Node 性能选择最佳的 JS 引...

    Yang_River 评论0 收藏0
  • CSS Sprite雪碧图的应用

    摘要:雪碧图的使用场景静态图片,不随用户信息的变化而变化。使用使用雪碧图之前,我们需要知道雪碧图中各个图标的位置。以上面的雪碧图为例实际雪碧图中各个小图片的起始位置和上面的展示图不同用一个来阐述它的使用方法。 CSS雪碧图,即CSS Sprite,也有人叫它CSS精灵图,是一种图像拼合技术。该方法是将多个小图标和背景图像合并到一张图片上,然后利用CSS的背景定位来显示需要显示的图片部分。 s...

    verano 评论0 收藏0
  • CSS Sprite雪碧图的应用

    摘要:雪碧图的使用场景静态图片,不随用户信息的变化而变化。使用使用雪碧图之前,我们需要知道雪碧图中各个图标的位置。以上面的雪碧图为例实际雪碧图中各个小图片的起始位置和上面的展示图不同用一个来阐述它的使用方法。 CSS雪碧图,即CSS Sprite,也有人叫它CSS精灵图,是一种图像拼合技术。该方法是将多个小图标和背景图像合并到一张图片上,然后利用CSS的背景定位来显示需要显示的图片部分。 s...

    Galence 评论0 收藏0
  • CSS > 关于雪碧图预处理和后处理方案的讨论

    摘要:预处理方案代表和预处理方案是预先指定需要生成的雪碧图切片元素,由工具合成后,得到相应的雪碧图和数据文件,开发中将二者投入使用。预处理方案一般以页面为单元组织雪碧图。结语关于雪碧图的处理方案的讨论就到此结束了。 广告:SF 里弄了个 CSS 小圈子,欢迎一起来讨论问题 前端小图标处理方案众多,本文主要介绍基于雪碧图的处理方案,分析雪碧图的预处理和后处理模式的得与失,以及在项目中通常会遇到...

    hyuan 评论0 收藏0
  • 雪碧图的生成

    摘要:写在开头的话最近参加了的一个任务自定义,样式,花了半天时间,摸索出了一条制作雪碧图的路径,跟大家分享,如果有更好的制作雪碧图的方法,希望告知一下,在此感谢。 写在开头的话 最近参加了2017ife的一个任务----自定义checkbox, radio样式,花了半天时间,摸索出了一条制作雪碧图的路径,跟大家分享,如果有更好的制作雪碧图的方法,希望告知一下,在此感谢。 首先 在网上的图标库...

    zhonghanwen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<