📜 ⬆️ ⬇️

Generating CSS Sprites with Gulp


While working on one big project, my partner and I thought about automating the process of collecting sprites on the project.
Prior to that, the sprites were collected by pens or using online services, which took enough time.
The project was already going to Gulp'om and it was decided to find a sprite assembler adapted for it.

There were several options:

The first option is difficult to install, there are several dependencies for which additional package managers had to be installed. If a new developer is added to the project, he will have to explain what is what. And this is not the path we have chosen. Also, there was no flexible configuration of the location of pictures in the sprite.

The remaining 3 options are implementations on one spritesmith engine. As a result, the choice fell on the official port for Gulp.

Installation


The very first thing to do is install Gulp on your computer. Official documentation will help you cope with this step.
Then we put gulp.spritesmith. In my case, the project is clean, so I put all the necessary dependencies.
')
npm i gulp gulp-stylus gulp.spritesmith --save 


Now you can proceed to the setting of the generator.

Customization


Before proceeding directly to the description of the task, let's look at the parameters that the function accepts.



Based on this, the simplest task will have the following form:
 gulp.task('sprite', function() { var spriteData = gulp.src('./src/assets/images/sprite/*.*') // ,      .pipe(spritesmith({ imgName: 'sprite.png', cssName: 'sprite.css', })); spriteData.img.pipe(gulp.dest('./built/images/')); // ,    spriteData.css.pipe(gulp.dest('./built/styles/')); // ,    }); 


We got this sprite:


And the following CSS:
Hidden text
 /* Icon classes can be used entirely standalone. They are named after their original file names. ```html <i class="icon-home"></i> ``` */ .icon-home { background-image: url(sprite.png); background-position: 0px 0px; width: 16px; height: 16px; } .icon-home_hover { background-image: url(sprite.png); background-position: 0px -16px; width: 16px; height: 16px; } .icon-instagram { background-image: url(sprite.png); background-position: 0px -32px; width: 16px; height: 16px; } .icon-instagram_hover { background-image: url(sprite.png); background-position: 0px -48px; width: 16px; height: 16px; } .icon-pin { background-image: url(sprite.png); background-position: 0px -64px; width: 12px; height: 16px; } .icon-pin_hover { background-image: url(sprite.png); background-position: 0px -80px; width: 12px; height: 16px; } .icon-tras_hover { background-image: url(sprite.png); background-position: 0px -96px; width: 16px; height: 16px; } .icon-trash { background-image: url(sprite.png); background-position: 0px -112px; width: 16px; height: 16px; } .icon-user { background-image: url(sprite.png); background-position: 0px -128px; width: 16px; height: 16px; } .icon-user_hover { background-image: url(sprite.png); background-position: 0px -144px; width: 16px; height: 16px; } 



Fine tuning

Our project uses the Stylus CSS preprocessor, so it will be more convenient for me to save it as a .styl file with variables.
For compactness, I turned on the binary-tree image distribution algorithm. All variables, for clarity, I give the prefix s- . I turn off the generation of mixins and put them into a separate file. And I create my own CSS template, because by default a lot of unnecessary garbage is generated, which decently inflates the file and is not used by me.

As a result, the sprite will look like this:


js + stylus code
 gulp.task('sprite', function() { var spriteData = gulp.src('./src/assets/images/sprite/*.*') // ,      .pipe(spritesmith({ imgName: 'sprite.png', cssName: 'sprite.styl', cssFormat: 'stylus', algorithm: 'binary-tree', cssTemplate: 'stylus.template.mustache', cssVarMap: function(sprite) { sprite.name = 's-' + sprite.name } })); spriteData.img.pipe(gulp.dest('./built/images/')); // ,    spriteData.css.pipe(gulp.dest('./src/styles/')); // ,    }); 

 $s-book = 16px 0px -16px 0px 16px 16px 80px 64px 'sprite.png'; $s-book_hover = 48px 16px -48px -16px 16px 16px 80px 64px 'sprite.png'; $s-comments = 0px 16px 0px -16px 16px 16px 80px 64px 'sprite.png'; $s-comments_hover = 16px 16px -16px -16px 16px 16px 80px 64px 'sprite.png'; $s-compose = 32px 0px -32px 0px 16px 16px 80px 64px 'sprite.png'; $s-compose_hover = 32px 16px -32px -16px 16px 16px 80px 64px 'sprite.png'; $s-faceboo_hover = 0px 32px 0px -32px 16px 16px 80px 64px 'sprite.png'; $s-facebook = 16px 32px -16px -32px 16px 16px 80px 64px 'sprite.png'; $s-globe = 32px 32px -32px -32px 16px 16px 80px 64px 'sprite.png'; $s-globe_hover = 48px 0px -48px 0px 16px 16px 80px 64px 'sprite.png'; $s-home = 0px 0px 0px 0px 16px 16px 80px 64px 'sprite.png'; $s-home_hover = 48px 32px -48px -32px 16px 16px 80px 64px 'sprite.png'; $s-instagram = 0px 48px 0px -48px 16px 16px 80px 64px 'sprite.png'; $s-instagram_hover = 16px 48px -16px -48px 16px 16px 80px 64px 'sprite.png'; $s-pin = 32px 48px -32px -48px 12px 16px 80px 64px 'sprite.png'; $s-pin_hover = 44px 48px -44px -48px 12px 16px 80px 64px 'sprite.png'; $s-tras_hover = 64px 0px -64px 0px 16px 16px 80px 64px 'sprite.png'; $s-trash = 64px 16px -64px -16px 16px 16px 80px 64px 'sprite.png'; $s-user = 64px 32px -64px -32px 16px 16px 80px 64px 'sprite.png'; $s-user_hover = 64px 48px -64px -48px 16px 16px 80px 64px 'sprite.png'; 



Using


Sprite is generated, stylus file with variables is - what's next?
Then we will be helped by work with all this mixins, which the plugin generates by default and which we have disabled.
For them, I created a separate file mixins.styl .

Contents of the mixins.styl file:
 spriteWidth($sprite) { width: $sprite[4]; } spriteHeight($sprite) { height: $sprite[5]; } spritePosition($sprite) { background-position: $sprite[2] $sprite[3]; } spriteImage($sprite) { background-image: url(../images/$sprite[8]); } sprite($sprite) { spriteImage($sprite) spritePosition($sprite) spriteWidth($sprite) spriteHeight($sprite) } 


The main mixin for us is sprite($sprite) . Instead of $sprite we $sprite the variable necessary to us. For example, sprite($s-home) .
The result is the following:
 background-image:url("../images/sprite.png"); background-position:0 0; width:16px; height:16px 

Mixin allows us to immediately display the width and height of the image - this is very convenient, especially when using pseudo-elements for decoration.
Working example

Problems


For all the time of using this solution, I met only one problem.
When :hover and :active icon will flash. This happens because the sprite mixin generates a background-image each time and the browser substitutes this image when it is hover.
After some thought and reading the documentation of the stylus , a solution was found.
We just need to check for the presence of the above pseudo-classes at the selector. If they are, then we skip the output of spriteImage($sprite) .

Final mixin
 sprite($sprite) if !match('hover', selector()) && !match('active', selector()) spriteImage($sprite) spritePosition($sprite) spriteWidth($sprite) spriteHeight($sprite) 


Unfortunately, it’s impossible to foresee all the options - sometimes it can be a class change through js, so we can just use
 spritePosition($sprite) 

if the picture was previously announced.

Total


I have been working with this solution for almost a month and I can say that it saves a lot of time. Strive to automate any routine and use your time as efficiently as possible.

I have prepared a repository with a working example for you, which you can use as a basis for your projects or just watch its work.

Links


Source: https://habr.com/ru/post/227945/


All Articles