Сейчас уже много где написано и упомянуто про технику CSS sprites (aka CSS Image Maps). Я не буду открывать Америку и рассказывать о ней дотошно еще раз, а просто хочу привести несколько примеров и полезных ссылок. И пару советов из собственной практики.
Сама техника заключается в том, что мы создаем комбинированное изображение, из которого затем «вырезаем» с помощью свойств background-position
нужный нам в данном случае кусок. На текущем уровне поддержки браузерами (я полагаю, что 99,9%) оно является просто must-have для любого уважающего себя интернет-ресурса (ибо позволяет сократить число запросов к серверу, отделить поведение от представления, возложить труд по анимации на CSS-движок браузера, а не на JS-движок, т.е. это будет работать даже с выключенными скриптами, и много-много прочих «вкусностей»). Но обо всем по порядку. Поехали.
Если кому-то хочется более подробно ознакомится с мат. частью, то порекомендую обратиться к следующей статье на русском, там техника расписывается во всех красках, в конце приведены некоторые ссылки (хм, там уже и ссылка на мой перевод про оптимизацию затесалась, оригинально :).
Обычно таким термином называют смену графической картинки при наведении на нее мышки, своеобразный call-to-action. У вебмастеров сложилась дурная практика делать такие эффекты через onmouseover/onmouseout
на картинках. Я не буду говорить о том, что это прямое нарушения принципа разделение представления от поведения и несемантическая (в лучшем случае, в худшем — еще и невалидная) верстка. Это просто плохо, очень плохо. Я просто дам простейший пример, когда это делается средствами CSS, и является семантически-правильным (в большинстве случаев это ссылка, но с элементами форм приходится немного повозиться, согласен). Итак, примеры:
Простая кнопка About Us. При наведении просто показывается другая картинка.
Более интересный пример с анимированный логотипом. При наведении показывается анимированная часть картинки, логотип «оживает», однако за это приходится платить размером (20 Кб).
Под таким термином я понимаю случаи, когда в одном файле содержатся нескольких «динамических кнопок». В общем, при первом взгляде на картинки все должно быть ясно.
Еще один пример с фиксированными по ширине кнопками
Матрица кнопок. Опять-таки, все фиксировано.
Еще одна матрица. На этот раз меню на Apple.com. За пример спасибо
Еще один пример с фиксированными кнопками. Авторы гарантируют, что в IE не будет происходить мигание фона (при наведении, фактически, фоновая картинка не меняется, просто фон становится прозрачным и «просвечивает» фон родителя. Правда, я так понимаю, это требует дополнительных, возможно, несемантических элементов в верстке. В общем, на любителя, но в определенных случаях можно использовать).
Я намеренно выделил этот пункт, ибо в предыдущем все области были одинаковыми, а в данном разделе размер областей может быть, вообще говоря, произвольным. Одним из хинтов является совмещение разных областей, чтобы они занимали минимум места. Эта техника как раз и заменила классический Image Map.
Классические примеры без использованию техники CSS Sprites. Заметны задержки при отображении отдельных областей на общей картинке.
Области не пересекаются. Размер картинок, показываемых при наведении, совпадает с размером исходных картинок.
Области также не пересекаются, просто в отличие от предыдущего случая, они все расположены горизонтально.
В данный раздел я отнес все примеры, которые используют общую картинку для отображения статической графики, не прибегая к динамическим эффектам.
Набор иконок. Основной опасностью таких файлов является «наложение» фоновых картинок одного блока на фон другого. Лучше всего это видно при увеличении размера шрифта: блок становится выше или длиннее, и запаса полей данного изображения уже не хватает, в результате у одного элемента отображается сразу несколько иконок. Непорядок. Как с ним бороться, я расскажу ниже в общих советах по созданию ресурсных картинок для CSS sprites.
В этом случае авторы поступают наиболее мудро: они жестко ограничивают размеры контейнера, у которого заданы определенные фоновые картинки, поэтому даже при увеличенном тексте картинка не «ломается» (однако, текст становится нечитаемым). Как бороться с последней напастью я также расскажу в конце заметки.
Здесь я выделил пару случаев, когда авторы стараются максимально оптимизировать число загружаемых файлов и объединяют порядка десятка различных картинок в одном файле.
Комбинированный пример. Автор использует ресурсный файл как для элементов списка (и та же самая проблема), так и для фона обычных картинок (с фиксированными шириной и высотой). В последнем случае, естественно, все ок.
Мой собственный пример. Для всех «статичных» картинок — один файл. Проблем при любом масштабировании текста не наблюдается.
Оговорюсь сразу, онлайн-генераторами не пользовался, предпочитаю делать все «ручками» в Photoshop'е.
www.csssprites.com. Довольно минималистичный дизайн, есть возможность загружать несколько исходных файлов.
printf.ru/spritr/. За пример спасибо
spritegen.website-performance.org. Много настроек, позволяет гибко генерить и сам CSS-фрагмент, но все картинки нужно загружать одним архивом.
Итак, самое вкусное. Для начала я бы советовал разбить все фоновые картинки на 5 групп:
repeat
)repeat-x
)repeat-y
)no repeat
)Выделение первой группы опционально, она может быть объединена с пятой, но тут уже надо решать на конкретных случаях (да и автор сайта выше решил, что 20 Кб его посетители переживут, и не побоялся их объединить). Откуда взялось разделение на остальные группы? Из очень простых соображений: если картинка будет повторяться по какому-то направлению, то по этому направлению она должна быть она-единственная в своем «окне», иначе повторяться будет не только она одна. Также я бы порекомендовал ориентироваться на общий размер файла в 10-20 Кб, если файл получается больше, то лучше подключать больше одного.
Далее, все картинки из группы 2 оставляем, как есть (вообще говоря, можно подумать над их преобразованием в стилевые правила для самых простых случаев, но это уже тема для отдельной дискуссии на тему особых извращений). Все картинки из группы 3 можно склеить по вертикали (тогда в своем горизонтальном окне они будут единственны), все картинки из группы 4 — по горизонтали. Что же делать с группой 5?
Тут нам нужно понять, для какой цели будет использовать каждая картинка. Если она будет изображать фиксированную по размерам кнопку, то ее можно размещать в любом месте итогового ресурсного файла, если она будет использована как иконка для списка (размещение в левом верхнем углу элемента), то мы должны очистить все пространство правее и ниже ее, чтобы при любом увеличении такого элемента (а «растут» элементы у нас всегда вниз и вправо) ничего лишнего не выводилось. Как пример можно привести картинку с последнего ресурса. В таком случае в иконки располагаются не вертикально, а «лесенкой».
Описанная выше проблема с изменением размера надписей в фиксированных кнопках (фон у них фиксированный, поэтому мы не можем их раздвигать при увеличении шрифта, и он обрезается) может быть преодолена путей разбиения фона на 4 части (угловые) и задания соответствующего цвета фона для всех элементов. Однако, это повлечет наличие, как минимум, 4 вложенных элементов для отображения каждого угла. Не во всех случаях это допустимо семантически (да, можно генерить дополнительную разметку JavaScript'ом, но насколько оно того будет стоить? Лучше решать в каждом конкретном случае).