Техника CSS Sprites

Рассмотрев все аспекты объединения текстовх файлов, перейдем к графической и мультимедийной информации. Сейчас уже много где написано и упомянуто про технику CSS Sprites (или CSS Image Maps). Ниже приведены несколько примеров и полезных ссылок. И пара советов, где и как этот метод может быть применим наиболее оптимальным образом.

Сама техника заключается в том, что мы создаем комбинированное изображение, из которого затем «вырезаем» с помощью CSS-свойства background-position нужный нам в данном случае кусок. На текущем уровне поддержки браузерами (порядка 99,9%) она является просто обязательной для любого уважающего себя веб-ресурса, так как позволяет сократить число запросов к серверу — а кроме этого отделить поведение от представления, и возложить труд по анимации на CSS-движок браузера, а не на JavaScript-движок (т.е. это будет работать даже с выключенными скриптами), и много-много прочих «вкусностей». Но обо всем по порядку.

Простой rollover-эффект

Обычно таким термином называют смену графической картинки при наведении на нее мыши, своеобразный призыв к действию (как его любят называть маркетологи). У вебмастеров сложилась дурная практика делать такие эффекты через onmouseover/onmouseout на картинках.

Это прямое нарушения принципа разделение представления от поведения и несемантическая (в лучшем случае, в худшем — еще и невалидная) верстка. И вообще, это очень плохо. В данном случае это делается средствами CSS и является семантически-правильным (в большинстве HTML-документов — это ссылка, но с элементами форм приходится немного повозиться, однако, тоже ничего сверхъестественного).

Пример: при наведении просто показывается другая картинка.

SpeedUpYourWebsite.v1.2_img_16

Рис. 16. Пример фонового изображения для простого rollover-эффекта. Источник: www.websiteoptimization.com

Соответствующая часть в CSS-коде будет выглядеть примерно так:

a.sprited {
     background: yellow url(http://site.ru/img/button.png) 0 0 no-repeat; 
     width: 100px; 
     height: 20px;
}
a.sprited:hover { 
     background-position: -100px 0; 
     background-color: red;
}

При наведении на ссылку фоновое изображение под ней «уедет», и покажется правая его часть (ибо она изначально скрыта жесткими размерами самой кнопки). Дополнительно мы обеспечили обратную совместимость для тех пользователей, у которых отключены картинки. Для них мы меняем цвет фона при наведении (если картинки в браузере включены, то изображение покажется поверх цвета).

Сложный rollover-эффект

Под таким термином стоит понимать те случаи, когда в одном файле содержатся нескольких «динамических кнопок». Например, это может быть такое изображение:

SpeedUpYourWebsite.v1.2_img_17

Рис. 17. Пример фонового изображения для сложного rollover-эффекта. Источник: www.spegele.com

Проблемные места в IE

В некоторых версиях IE изменение расположения фона при наведении мыши отрабатывает не совсем корректно, и браузер запрашивает исходную фоновую картинку с сервера еще раз, что вызывает «мигание» картинки. Одним из вариантов борьбы с такой проблемой может стать изменение не позиции фонового элемента, а его прозрачности. Например, мы можем сразу задать параметры фона для элемента и его прямого потомка, а при наведении мыши менять фон дочернего элемента на прозрачный, тогда фон родителя будет просто просвечивать:

<a href=‖/‖><span>Начало</span></a>
a {
     background: yellow url(http://site.ru/img/button.png) 0 0 no-repeat;
      display: block; 
     height: 20px; 
     width: 100px;
}
a span { 
     background: red url(http://site.ru/img/button.png) -100px 0 no-repeat;
     display: block; 
     height: 20px; 
     width: 100px;
}
a:hover span { 
     background: transparent;
}

К сожалению, этот метод предполагает появление у элемента несемантического потомка для обеспечения графических эффектов. Более стандартным вариантом будет вызов специфичного для IE метода backgroundImageCache (через try или любое другое условие, гарантирующее обратную совместимость с остальными браузерами):

try { 
     document.execCommand(«BackgroundImageCache», false, true);
} catch (e) {}

В данном случае мы форсируем кэширование фоновых изображений, что предотвращает описанную выше ошибку.

CSS Image map

Этот пункт стоит намеренно выделить, ибо он подразумевает более свободное использование ресурсного файла для «подсветки» какого-либо изображения при наведении. Если в предыдущих случаях области были одинакового размера, то тут уже размер областей может быть, вообще говоря, произвольным. Одним из преимуществ такого подхода является совмещение разных областей, чтобы они занимали минимум места. Эта техника как раз и заменила классический Image Map.

SpeedUpYourWebsite.v1.2_img_18

Рис. 18. Пример изображения для CSS Image Map. Источник: www.acronis.com

Статичные картинки

Кроме динамических эффектов CSS Sprites широко используется и для объединения статических изображений. Давайте рассмотрим различные плюсы и минусы этого подхода.

Основной опасностью склеивания большого количества иконок в одном месте являются артефакты при увеличении шрифта: посторонняя часть фонового изображения проявляется совершенно не в том месте, где его ожидали, и у пользователя возникает ощущение, что страница «разваливается». Блок становится выше или длиннее, запаса полей данного изображения уже не хватает, в результате у одного элемента отображается сразу несколько иконок. Непорядок. Как с ним бороться, будет рассказано немного ниже в общих советах по созданию ресурсных картинок для CSS Sprites.

В общем случае нужно жестко ограничивают размеры контейнера, у которого заданы определенные фоновые картинки, чтобы даже при увеличенном тексте картинка не «ломалась» (однако, текст может стать нечитаемым из-за обрезания по границе блока). Как бороться с последней напастью, также будет рассказано в конце раздела.

В некоторых случаях возможно также объединение всех фоновых изображений на странице в одно-единственное. Такой подход значительно сокращает число запросов к серверу, однако, влечет и технологические сложности. Как пример можно привести следующее изображение:

SpeedUpYourWebsite.v1.2_img_19

Рис. 19. Пример фонового изображения «все-в-одном». Источник: webo.in

Онлайн-генераторы

www.csssprites.com. Обладает довольно минималистичным дизайном, есть возможность загружать несколько исходных файлов.

www.printf.ru/spritr/. В этом инструменте есть возможность загружать несколько файлов, очень милый дизайн, но, в целом, настроек мало.

spritegen.website-performance.org. Тут очень много настроек, также можно гибко создавать и сам CSS-фрагмент, но все картинки нужно загружать одним архивом.

Полезные советы

Итак, самое вкусное. Для начала стоит разбить все фоновые картинки на 5 групп (однако, пятая группа может быть объединена с любой из первых четырех).

  1. Анимированные картинки
  2. Те, которые предполагается повторять по всем направлениям (repeat)
  3. Те, которые предполагается повторять по горизонтали (repeat-x)
  4. Те, которые предполагается повторять по вертикали (repeat-y)
  5. И те, которые предполагается показывать только один раз (no-repeat)

Откуда взялось разделение на такие группы? Из очень простых соображений: если картинка будет повторяться по какому-то направлению, то по этому направлению она должна быть одна-единственная в своем «окне», иначе повторяться будет не только она одна. Также стоит ориентироваться на общий размер файла в 10-20 Кб: если файл получается больше, то лучше подключать больше одного (соображения по разбиению файлов по размеру более подробно приведены в пятой главе).

Далее, все картинки из второй группы (повторяющиеся по всем направлениям) оставляем как есть (вообще говоря, можно подумать над их преобразованием в стилевые правила для самых простых случаев, но это уже тема для отдельной дискуссии). Все картинки из третьей группы можно склеить по вертикали (тогда в своем горизонтальном окне они будут единственными), все картинки из четвертой группы — по горизонтали. Что же делать с пятой группой?

Тут нам нужно понять, для какой цели будет использовать каждая картинка. Если она будет изображать фиксированную по размерам кнопку, то ее можно размещать в любом месте итогового ресурсного файла. Если она будет использована как иконка для списка (размещение в левом верхнем углу элемента), то мы должны очистить все пространство правее и ниже ее. Таким образом, при любом увеличении такого элемента (а «растут» элементы у нас всегда вниз и вправо) ничего лишнего не выводилось. В таком случае иконки располагаются не вертикально, а «лесенкой» (из правого верхнего угла в левый нижний).

SpeedUpYourWebsite.v1.2_img_20

Рис. 20. Пример фонового изображения с расположением картинок «лесенкой». Источник: webo.in

Описанная выше проблема с изменением размера надписей в фиксированных кнопках (фон у них фиксированный, поэтому мы не можем их раздвигать при увеличении шрифта, и он обрезается) может быть преодолена путем разбиения фона на 4 части (угловые) и задания соответствующего цвета фона для всех элементов. Однако это повлечет наличие, как минимум, 4 вложенных элементов для отображения каждого угла. Не во всех случаях это допустимо семантически. Да, можно создавать дополнительную разметку при помощи JavaScript, но насколько оно того будет стоить? Это лучше решать в каждом конкретном случае.

Давайте теперь перейдем к методам, позволяющим вставлять графическую информацию непосредственно в текстовые файлы без необходимости запроса внешних ресурсов.

Posted in Разгони свой сайт.