Latest posts

Advanced sprite generation using Compass (SASS)

Spriting, or sprite generation

Spriting is a way to improve performance in your website by putting many images (or icons) in a single larger image, in order to make a single HTTP request instead of many.

You could manually create the sprite map (the single larger image) using your favorite image editor and cutting it in CSS, maybe using a tool like SpriteCow to make the process simpler.

Or you can create sprite maps using Compass.

Creating sprites with Compass

The simple way

The simpler way to create a sprite with Compass requires you to import a folder of images in your project, then generate a class for each sprite. You can do that by using the following code:

// Required Compass tool import
@import "compass/utilities/sprites";
// Importing all the png images under the flags folder
@import "flags/*.png";
// Generate a CSS class for each sprite
@include all-flags-sprites;

Example of CSS output:

.flags-it,
.flags-de,
.flags-fr { 
  background: url('/images/flags-s34fe0604ab.png') no-repeat; }

.flags-it { background-position: 0 0; }
.flags-de { background-position: 0 -32px; }
.flags-fr { background-position: 0 -64px; }

This can be enough for your needs… but you want more, don’t you?

The considering pixel density + spacing between sprites + size generating + offset managing way

Skipping all the others way you can do sprites generation with Compass, I found out that if you have to do the following:

  • Generate dimensions of the box equals to the sprite ones
  • Use an offset inside the box
  • Spacing sprites inside the sprite map
  • Manage 1x, 2x, 3x density displays
  • Optimize sprite generation time

The only way to do spriting with Compass is to create your own mixins which use Compass base mixins under the hood.

_mixins.scss

I created the following mixins, that I usually put in a separate _mixins.scss partial.

// N-ple density sprite
@mixin useNxSprite($sprite, $spriteMap, $spriteUrl, /* OPTIONAL PARAMETERS -> */ $multiplier: 1, $renderSize: false, $offsetX: 0, $offsetY: 0) {
  $spritePosition: sprite-position($spriteMap, $sprite, $offsetX * $multiplier, $offsetY * $multiplier);
  background: transparent $spriteUrl no-repeat nth($spritePosition, 1) / $multiplier nth($spritePosition, 2) / $multiplier;
  @if ($multiplier > 1) {
    background-size: (image-width(sprite-path($spriteMap)) / $multiplier) (image-height(sprite-path($spriteMap)) / $multiplier);
  }
  @if ($renderSize) {
    height: image-height(sprite-file($spriteMap, $sprite)) / $multiplier;
    width: image-width(sprite-file($spriteMap, $sprite)) / $multiplier;
  }
}
 
// Single and double density sprite
@mixin use1x2xSprite($sprite, $sprite1xMap, $sprite2xMap, $sprite1xUrl, $sprite2xUrl, /* OPTIONAL PARAMETERS -> */ $renderSize: false, $offsetX: 0, $offsetY: 0) {
  @include useNxSprite($sprite, $sprite1xMap, $sprite1xUrl, 1, $renderSize, $offsetX, $offsetY);
  @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
    @include useNxSprite($sprite, $sprite2xMap, $sprite2xUrl, 2, $renderSize, $offsetX, $offsetY);
  }
}

_variables.scss

This is the file where you define all the variables for your site, that you’re going to use across all your scss files.

In your _variables.scss file you should define the spacing between sprites in sprite map images.

// Generic spacing (at 1x) for sprites
$spacing-sprites-generic: 10px;

_siteSprites.scss

This is the file where you define the variables and the mixins for your sprites.

I suggest to use a _sprites.scss partial different from you _variables.scss, and to @import _sprites.scss only in scss files that requires sprites. This speeds up build time a lot, by avoiding frequent images check on the file system.

// SiteSprites MAPS and URLS
$siteSprites1xMap: sprite-map("siteSprites1x/*.png", $spacing: $spacing-sprites-generic);
$siteSprites2xMap: sprite-map("siteSprites2x/*.png", $spacing: $spacing-sprites-generic * 2);
$siteSprites1xUrl: sprite-url($siteSprites1xMap);
$siteSprites2xUrl: sprite-url($siteSprites2xMap);

// SiteSprites mixin
@mixin siteSprites($spriteName, $renderSize: false, $offsetX: 0, $offsetY: 0) {
    @include use1x2xSprite($spriteName, $siteSprites1xMap, $siteSprites2xMap, $siteSprites1xUrl, $siteSprites2xUrl, $renderSize, $offsetX, $offsetY);
}

final_file.scss

In your final scss file you can use the sprite doing the following:

Standard usage

If you don’t need space around your sprite and you don’t want Compass to generate box dimensions for you, you can simply do the following.

@import "compass/utilities/sprites";
@import "_variables";
@import "_sprites";
 
// Simple usage
.example > .icon {
    @include siteSprites(small_arrow_right);
}

That will produce the following:

.example > .icon {
  background: transparent url('/img/siteSprites1x-s8e63b9f8b7.png') no-repeat 0 -80px;
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
  .example > .icon {
    background: transparent url('/img/siteSprites2x-s166aeb7845.png') no-repeat 0 -80px;
    background-size: 142.5px 137px;
  }
}

Advanced usage with spacing and size generation

If you want Compass to generate box dimensions for you and you want to leave a space of 10 pixels around the sprite you’re using, you should do the following.

@import "_variables";
@import "_sprites";
 
// Simple usage
.example > .placedIcon {
    @include siteSprites(small_arrow_right, true, 10, 10);
}

That will produce the following:

.example > .placedIcon {
  background: transparent url('/img/siteSprites1x-s8e63b9f8b7.png') no-repeat 10px -70px;
  height: 20px;
  width: 10px;
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
  .example > .placedIcon {
    background: transparent url('/img/siteSprites2x-s166aeb7845.png') no-repeat 10px -70px;
    background-size: 142.5px 137px;
    height: 20px;
    width: 10px;
  }
}

A new LazyLoad to improve your website performance

In the latest days I’ve been working on websites performance optimization and I realized that there is no way to take advantage of the progressive JPEG image format on websites if you’re using jQuery_lazyload. So after sending a pull request to its author, I decided to write my own lazy load, which turned out to be 6x faster.

LazyLoad is a fast, lightweight and flexible script for loading images only when they’re about to enter the viewport of a scrollable area, written in pure Javascript (no jQuery) and with an excellent support to the srcset attribute and to the progressive JPEG image format (which is performing good).

WEBSITE | DEMOS | GITHUB

Continue reading

PicturePolyfill 4 – the fastest picture tag polyfill

PicturePolyfill 4 is out!

Implementing responsive images in your site has never been so simple and fast.

Responsive image

Most important features

  • the <source> parsing algorithm behavior: it now exits at the first matching media query instead of at the last one, as the native implementation does
  • one img tag is now mandatory, as defined in the picture tag specification
  • the srcset attribute inside the img tag is now better managed, in browsers that support it
  • the script is now lighter than before, because the functions to create the img tag were removed
  • the script is now even faster because it now parses only the matching srcset attribute, and not all of them as before
  • the internal cache system is still in place and working fine but  you can avoid using it (just in case you need to) passing a parameter

Continue reading

SVG + PNG fallback made super-easy with Grunt and SVGZR

It was recently released the SVGZR Grunt Plugin, which is super useful to make SVG with PNG fallback usage super-easy, with Grunt.

10-metro_ui_dock_icon_set___678_svg_icons_by_monkee98-d5deacy

The plugin will help you to:

  • take all the SVG images from an input folder
  • compress the SVG removing useless data from the SVG format
  • embed all the SVG images in a CSS file (using the base64 encoding), each one with a specific class name referring to the file name
  • create a PNG sprite image as a fallback for legacy browsers

You can find the Grunt Plugin and more information at this SVGZR GitHub page, and you can install it as a NPM module.

Making of The Treasure of Front-end Island – Chapter 3 – The rising smoke

Ahoy, front-end pirates!

Welcome to the Chapter 3 of the Making of The Secret of Front-end Island saga: the Rising Smoke.

Front-end Island Rising Smoke

In the layout the smoke was composed by 5 gray circles at different opacity. Oh joy! I could avoid using images using markup and border-radius, and animate every smoke ball using CSS 3 only. Challenging, then funny. :)
Continue reading

Making of The Treasure of Front-end Island – Chapter 2 – The blowing clouds

Ahoy, front-end pirates!

Welcome to the Chapter 2 of the Making of The Secret of Front-end Island saga: the Blowing Clouds.

As I described before, in the Photoshop layout I got from the designer (Diego Sessa) I had the finished 1280 pixel wide layout, and I had the discretion of choosing animations, responsive behavior, and so on.

For the blowing clouds I decided to make a “blow left and right” effect using CSS 3 only. I also wanted the clouds to move at different speeds.
Continue reading

Making of The Treasure of Front-end Island – Chapter 1 – The splashing title

Ahoy, front-end pirates!

Welcome to the Chapter 1 of the Making of The Secret of Front-end Island saga: the Splashing Title.

Let’s start saying that in the Photoshop layout I got from the designer (Diego Sessa) I had the finished 1280 pixel wide layout, and I had the discretion of choosing animations, responsive behavior, and so on.

For the splash image I decided to make a “splash” effect using CSS 3 only. So the image had to start small, become bigger than it had to become, bounce back a little, and finally become of the final size. It also had to be shown of the final size in browsers that don’t support CSS 3 transitions.

Here are the steps of what I did:

Continue reading