9 December 2014

Долой абсолютные единицы в иконках-спрайтах

CSS

Спрайты — классный способ сократить количество запросов к серверу. Можно упаковать кучу иконок в один спрайт и прописать в CSS смещения для каждой иконки. Однако, очень неудобно, что нужно попиксельно всё это считать. Пиксели — значит никакой динамики. Если использовать пиксели, то кусочек спрайта будет отображаться фиксированным размером — независимо от того, выводится он внутри параграфа, или внутри заголовка. Это неправильно, мне кажется, и неудобно. Но, похоже, я нашёл интересный способ выводить иконки динамического размера.

В первую очередь, нужно перестать думать о спрайте, как о вещи с шириной и высотой, выраженной в пикселях. Спрайт на картинке в заголовке имеет размеры 500 на 100 пикселей, но его нужно воспринимать как спрайт, который имеет размер 10х2. В самом деле, какая разница, сколько у него пикселей? Главное то, что он содержит 10 иконок в ширину и две в высоту.

Во время вёрстки при описании спрайта просто нужно указать ширину и высоту фонового изображения в относительных единицах — я буду использовать EM. Так как спрайт имеет размер 10 на 2, его можно описать так:

.icon {
    background-image: url(http://i.imgur.com/DV0Bl7B.png);
    display: inline-block;

    /* Ширина — 10, высота — 2. */
    background-size: 10em 2em;

    /* Размеры иконки 1х1 — снова относительные единицы, а не абсолютные */
    width: 1em;
    height: 1em;
}

/* Конкретная иконка. Смещение прописывается опять же в относительных единицах */
.icon-ok-black {
    background-position: -7em -1em;
}


За счёт того, что все размеры указываются в относительных единицах, иконка будет автоматически подстраиваться под размер шрифта — в заголовке она будет соответствовать размеру шрифта заголовка, в абзаце — размеру шрифта абзаца, и так далее. Можно сделать один спрайт, например, с размером каждой иконки в 50 пикселей, и эти 50 пикселей будут всегда масштабироваться до размера 1em в текущем контексте.

Однако, имейте ввиду, что при масштабировании растровых изображений графика может размываться. Возможно, этот способ лучше всего подходит для векторной графики — SVG, например. Благодарю BaNru за ценное замечание.

Пример на JSFiddle: jsfiddle.net/vdfqdfen
Tags:спрайты
Hubs: CSS
+24
23.1k 258
Comments 54