Во время верстки макетов часто возникает необходимость разместить рядом с текстом ссылки небольшую иконку. Любому хорошему верстальщику хочется сделать такую иконку неотъемлемой частью ссылки. Самый распространенный метод решения этой задачи — поместить иконку на фон ссылки и добавить ссылке padding. К сожалению, этот метод накладывает ограничения на изображение, используемое в качестве иконки. Если мы хотим использовать один спрайт для всех иконок, то отступы между иконками зависят от размеров ссылок. При большом количестве иконок один спрайт может иметь весьма внушительные размеры, причем нередко большая часть изображения пуста. Можно, конечно, каждую иконку сохранить отдельным файлом, но каждый такой файл увеличит время загрузки страницы. В результате мы вынуждены искать баланс между размером и количеством используемых изображений. Задача усложняется по мере добавления на страницу новой графики.

Слева — старый вариант спрайта. На самом деле все иконки в нем расположены вертикально в ряд, а не в два ряда, как на картинке Слева — старый вариант спрайта. На самом деле все иконки в нем расположены вертикально в ряд, а не в два ряда, как на картинке

Я предлагаю новый метод, позволяющий оптимально использовать файл спрайта, и при этом никак не ограничивающий размеры ссылок. В основе этого метода лежит использование псевдо-элемента :before. Поддержка этого псевдо-элемента есть во всех современных браузерах. IE7 современным браузером мы не считаем, в нем иконки просто не появятся. Итак, приступим.

Для начала создадим спрайт со всеми нужными нам иконками. Совершенно не важно, в каком порядке они размещены. В качестве примера для этой статьи я выбрал несколько иконок из популярного набора от Fat Cow Hosting:

Мой спрайт для демонстрации метода Мой спрайт для демонстрации метода

Я рекомендую оставлять между иконками 1-2 пустых пиксела, в противном случае при увеличении текста средствами браузера края соседних иконок будут попадать в видимую область.

Для начала создадим базовый класс .icon для всех иконок:

.icon {
     /* Это свойство необходимо, чтобы текст ссылки не
     * отрывался от иконки при переносе. Недостаток в том, что
     * сама ссылка также не будет переноситься по словам, если
     * она слишком длинная */
    white-space: nowrap; 
}
.icon:before {
    content: '';
    background-image: url('sprite-icon.png'); /* подставьте сюда адрес своего спрайта */
    background-repeat: no-repeat;
    background-position: 16px 16px; /* здесь нужно указать координаты иконки по умолчанию */
    margin: 0 3px;
    left: 0;
    top: 3px; /* это свойство смещает иконку вниз относительно базовой линии текста */
    position: relative;
    width: 16px;
    height: 16px;
    display: inline;
    display: inline-block;
}

Теперь открываем сервис SpriteCow, загружаем в него наш спрайт, определяем координаты всех иконок и создаем для каждой отдельный класс с этими координатами. Сам сервис предлагает не только координаты, но и размеры и другие свойства, но нам все это не нужно.

.icon-blogger:before { background-position: 0 0; }
.icon-email:before { background-position: 0 -18px; }
.icon-deviantart:before { background-position: 0 -36px; }
.icon-evernote:before { background-position: -17px 0; }
.icon-flickr:before { background-position: -17px -18px; }
.icon-gamespot:before { background-position: -17px -36px; }
.icon-grooveshark:before { background-position: -34px 0; }
.icon-lastfm:before { background-position: -34px -18px; }
.icon-linkedin:before { background-position: -34px -36px; }
.icon-netvibes:before { background-position: -51px 0; }
.icon-reddit:before { background-position: -51px -18px; }
.icon-tumblr:before { background-position: -51px -36px; }
.icon-twitter:before { background-position: -68px 0; }
.icon-vimeo:before { background-position: -68px -18px; }
.icon-youtube:before { background-position: -68px -36px; }
Счастливчики, использующие less или sass, могут включить общий класс .icon в каждый из классов конкретных иконок, после чего ссылке достаточно будет добавить только последний, например class="icon-youtube" вместо class="icon icon-youtube"

По сути это все, осталось только добавить ссылке класс icon и соответствующий класс иконки, и можно пользоваться. Но я предлагаю читателям создать еще один класс .icon-block для использования иконок в блочных элементах (например, ссылках в виде кнопок).

.icon-block {
    padding-left: 20px; /* Это значение для каждой кнопки нужно будет переопределять */
    position: relative; 
}
.icon-block:before {
    content: '';
    background-image: url('sprite-icon.png');
    background-repeat: no-repeat;
    background-position: 16px 16px;
    margin: 0;
    margin-top: -8px;
    left: 0;
    top: 50%;
    position: absolute;
    width: 16px;
    height: 16px;
    display: block;
}

Для демонстрации использования этого класса создадим кнопочку отправки почты:

.button {
    /* стили самой кнопки не имеют значения, поэтому приведу лишь основные */
    margin: 6px;
    border: 1px solid #000;
    padding: 7px 15px 8px;
    display: block;
    float: left;
    /* а вот тут мы задаем левый отступ с учетом размеров иконки */
    padding-left: 40px;
}
.button.icon-block:before {
    /* зададим отступ иконки от левого края кнопки */
    margin-left: 15px;
}

Теперь в нашей кнопке мы можем использовать любую из уже определенных иконок, добавляя ей классы icon-block и класс с координатами самой иконки. Страницу с примерами ссылок с иконками можно посмотреть здесь.