Making css sprites more responsive on retina displays and more [less]

  • Tutorial
image

Why do we need sprites at all?


I will write only briefly why this is necessary, since the advantages and disadvantages of css-sprites have been described many times on the Habré .
  • Firstly, using sprites, we speed up page loading; in the case of using icons, you can create a universal tool for use in projects;
  • Secondly, not all devices with high ppi (for example, Windows Phone 7.5-7.8, Android up to version 4 on the stock browser) support the use of webfonts.
  • Easy integration using special sprite generation services

Problem statement or so that life does not seem raspberry


Using css sprites with many elements, the problem arises of creating css properties with background-position; They need to write a lot, sometimes a lot. Of course, many services for generating sprites help us - they give out along with the sprite a css / less / sass - file with coordinates. But almost always everything is rigidly tied to pixels:
  • Changing the size (for example, for retina screens) of the original sprite file, everything "goes";
  • We cannot change the size of the container element where we want to insert, say, an icon so that this icon scales: the properties background-size: cover/contain/100%do not work for obvious reasons;

Using sprites prepared for 72ppi on phones, tablets and new retina laptops causes blurring of images and they look ugly ...

Disclaimer about cross-browser compatibility, cross-platform and cross-something else
We will use css3 in this method only for displays with ppi higher than the standard 72. Similar displays appeared relatively recently, and no IE 7.0- IE8.0 and similar old versions of Firefox or Opera will not stand there. With the mobile segment, too, everything is in order, support for media queries is implemented everywhere .

Let's start forming a less snippet


I’ll immediately notice that nobody forces to use less on a working project, everything can be compiled into regular css. There are a lot of similar programs for mac, WinLess will be useful for windows .
Now I will consider a special case of a sprite - a sprite with icons generated by a wonderful resource icomoon.io What

would we do with simple css if we needed to configure a sprite for retina? Most likely, we would refuse to use a high-resolution sprite. Perhaps they would connect it only for devices with high ppi.
But here we are faced with the problem of scaling this sprite to fit our size. And this, excepttransform: scale(x);just do not solve it, and you have to redraw the sprite, rewrite everything background-position. And everything would be fine, but sometimes the number of icons goes off the scale, and indeed I would like a universal solution .

I have them


So let's get started:
  • The first thing we need is to generate 2 sprites (3 can be, if we want to cover 400+ ppi) and a css code for them. This is done easily through the service I quoted above. I generated 145 icons, sizes 16px (25kb), 32px (62kb) and 64px (163kb)
    Initially, the attached css file for 16px icons looks like this: (I intentionally reduced it to four icons so as not to scare me with huge sheets of code)
    .icon-rss,.icon-e-mail,.icon-youtube,.icon-mailru {
    	display: inline-block;
    	width: 16px;
    	height: 16px;
    	background-image: url(sprites.png);
    	background-repeat: no-repeat;
    }
    .icon-rss {
    	background-position: 0 0;
    }
    .icon-e-mail {
    	background-position: -32px 0;
    }
    .icon-youtube {
    	background-position: -64px 0;
    }
    .icon-mailru {
    	background-position: -96px 0;
    }
    

  • Then we find out the size of the sprite image. For 16px icons, it was 496px. This value will be the reference for our less code. Now it’s worth adding a linebackground-size: 496px;
  • Now we have to get rid of the units in all this css-sprite, replacing " px" with a variable, by default equal to 1px. Let her be called size. This is easily done by AutoCorrect. Along the way, do not forget to rename the file to the less extension and include the main less-file of your project:
    @size: 1px;
    .icon-rss,.icon-e-mail,.icon-youtube,.icon-mailru {
    	display: inline-block;
    	width: 16*(@size);
    	height: 16*(@size);
    	background-image: url(sprites.png);
    	background-repeat: no-repeat;
    	background-size:496*(@size);
    }
    .icon-rss {
    	background-position: 0 0;
    }
    .icon-e-mail {
    	background-position: -32*(@size) 0;
    }
    .icon-youtube {
    	background-position: -64*(@size) 0;
    }
    .icon-mailru {
    	background-position: -96*(@size) 0;
    }
    
  • It is important to note that we cannot just add the resulting mixins to the tags - we have the width and height in the classes, which means we will add them to pseudo-elements ::beforeor::after
  • @media less supports queries anywhere in the code: depending on the pixel density, we will attach a particular file.
    @size: 1px;
    .icon-rss,.icon-e-mail,.icon-youtube,.icon-mailru {
    	display: inline-block;
    	width: 16*(@size);
    	height: 16*(@size);
    	background-image: url(sprites.png);
    @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: 192dpi),
    only screen and (                min-resolution: 2dppx) { 
    	background-image: url(sprites32.png);
    }
    @media 
    only screen and (-webkit-min-device-pixel-ratio: 4),
    only screen and (   min--moz-device-pixel-ratio: 4),
    only screen and (     -o-min-device-pixel-ratio: 4/1),
    only screen and (        min-device-pixel-ratio: 4),
    only screen and (                min-resolution: 360dpi),
    only screen and (                min-resolution: 4dppx) { 
    	background-image: url(sprites64.png);
    }
    	background-repeat: no-repeat;
    	background-size:496*(@size);
    }
    .icon-rss {
    	background-position: 0 0;
    }
    .icon-e-mail {
    	background-position: -32*(@size) 0;
    }
    .icon-youtube {
    	background-position: -64*(@size) 0;
    }
    .icon-mailru {
    	background-position: -96*(@size) 0;
    }
    

Comments for practical application


  1. You do not have to generate three different sprites through the generator program at once. You can generate one (for very-retina screens), get a precious css-file, and then make a reduced version of the sprite for ordinary devices (not retina) through a graphical editor.
  2. I do not use " px" in my projects . Instead, I sizeassign a value to the variable in units of measure " rem". This gives freedom to change the size of the icons to the necessary, and if we open the site from a tablet, these ones rem become a little larger, because I set a slightly larger font size for tablets, for example:
    @media (min-width: 768px) and (max-width: 1366px) {
         html {font-size: 120%;}
    }
    


When to use this technique


  • For the ability to load sprites of different quality for retina / non-retina screens;
  • When it is supposed that the icon will be resized during project development;
  • When to adapt the original sprite when creating a mobile version of the site;
  • In my practice, I use this method only when webfonts are not supported by the device. In any other cases, it is easier to use an icon font: here you can change the color, set the shadow, and not worry about the size and blur


PS: Please write about spelling, syntactic and lexical errors in the LAN.
PPS: This material does not purport to add measures and weights to the chamber, and the examples used are not perfect. Guru-less / sass in this post will not find anything special, but for beginners it will be useful.

Only registered users can participate in the survey. Please come in.

Should I add articles about less-mixins and snippets?

  • 60.1% Yes, less is a convenient tool, I would like more examples 190
  • 20.2% No, I write in sass / scss and do not see anything striking in these examples 64
  • 13.2% It is worth focusing on the layout for mobile devices 42
  • 23.4% I believe that the preprocessor to use css is not worth staying true only css 74

Also popular now: