CSS спрайты
Дата публикации: 07.07.2011
CSS спрайты — отличный метод, позволяющий сократить количество необходимых запросов к серверу для загрузки изображений. По этому методу написано уже много книг и статей. Если у тебя на сайте много изображений (в большей степени касается логотипов, иконок, фоновых изображений, флагов и т.д.) ты можешь вместо множества мелких изображений сделать одно большое со всеми ними внутри и при помощи CSS определять, какая конкретно часть изображения в каком контейнере должна показываться.
Этот метод влияет на производительность, но в случае с мобильными технологиями, прежде чем использовать его, мы должны хорошенько подумать и проанализировать все возможные проблемы. Во-первых, для нормальной работы нужна полная поддержка CSS свойства background-position (это свойство включено в мобильные стандарты, так что это не такая уж и проблема). Второй момент — мы не будем использовать теги <img>. Вместо них будет использовать блочный элемент (<div>) или любой другой преобразованный в блочный элемент ( display: block). Это значит, что мы не можем использовать для изображения альтернативный текст и пока не загрузиться CSS файл, браузер не будет знать, сколько нужно выделить места под то или иное изображение.
В некоторых браузерах этот метод может повлиять на производительность рендеринга, потому как при каждом применение спрайта его большое изображение будет дублироваться в памяти браузера. Здесь нам нужно установить баланс между ресурсами, которые были сэкономлены за счет сокращения количества запросов на сервер и ресурсами, которые будут дополнительно затрачены на рендеринг в некоторых браузерах.
Примеры и совместимость
Давай сделай пример кода при помощи двух методов: использование исходного блочного элемента (<div>) и использование исходного встроенного элемента (<a>), преобразованного в блочный элемент.
Оригиналом документа без CSS спрайтов является следующий список стран:
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Documento sin título</title> <style type="text/css"> ul { list-style: circle; } ul li { padding: 0px; margin-bottom: 5px; } ul li img { margin: 0px 10px 0px 0px; vertical-align: middle; border: 1px solid gray; } </style> </head> <body> <h1>The Best Seller</h1> <h2>Select your nearest country</h2> <ul> <li><img src='ar.png' width='30' height='19' alt='AR' /> <a href='ar'>Argentina</a></li> <li><img src='br.png' width='30' height='19' alt='BR' /> <a href='br'>Brazil</a></li> <li><img src='fi.png' width='30' height='19' alt='FI' /> <a href='fi'>Finland</a></li> <li><img src='jp.png' width='30' height='19' alt='JP' /> <a href='jp'>Japan</a></li> <li><img src='es.png' width='30' height='19' alt='ES' /> <a href='es'>Spain</a></li> <li><img src='us.png' width='30' height='19' alt='US' /> <a href='us'>United States</a></li> </ul> </body> </html>
В предыдущем примере используется шесть изображений, которые могут быть сконвертированы в одно большое изображение (получается на пять HTTP запросов и заголовков меньше) при помощи следующего кода:
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Documento sin título</title> <style type="text/css"> ul { list-style: circle; } ul li { padding: 0px; margin-bottom: 5px; } ul li div { /* а вот и наше большое изображение */ background:url(sprite.png); width: 30px; height: 19px; float: left; border: 1px solid gray; margin-right: 10px; } </style> </head> <body> <h1>The Best Seller</h1> <h2>Select your nearest country</h2> <ul> <li><div style="background-position: 0px 0px;"></div> <a href='ar'>Argentina</a></li> <li><div style="background-position: 0px −29px;"></div> <a href='br'>Brazil</a></li> <li><div style="background-position: 0px −58px;"></div> <a href='fi'>Finland</a></li> <li><div style="background-position: 0px −87px;"></div> <a href='jp'>Japan</a></li> <li><div style="background-position: 0px −116px;"></div> <a href='es'>Spain</a></li> <li><div style="background-position: 0px −145px;"></div> <a href='us'>United States</a></li> </ul> </body> </html>
Результат на рисунке 7.8:
Рис. 7.8. В поддерживающих браузерах использование техники CSS спрайтов дает возможность добиться одинакового результата, используя одно единственное изображение вместо использования шести отдельных изображений для флагов.
Есть много онлайноввых CSS-генераторов, в которых ты можешь загрузить все изображения и уже через секунду получить одно большое изображение и CSS код для замены всех исходных тегов <img>. Примеры на http://spritegen.website-performance.org и на http://csssprites.com.
Теперь давай посмотрим, как применить этот же самый метод к такому изначально не блочному элементу как тег <a>. Нужно только не забыть сделать внутренний отступ, чтобы текст не налез на изображение. Код будет выглядеть так:
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Documento sin título</title> <style type="text/css"> ul { list-style: circle; } ul li { padding: 0px; margin-bottom: 5px; } ul li a { /* We define the large image to all divs that represent an image */ background:url(sprite.png); /* We need to create block elements */ display: block; /* We need the background to not be repeated */ background-repeat: no-repeat; height: 19px; padding-left: 40px; } </style> </head> <body> <h1>The Best Seller</h1> <h2>Select your nearest country</h2> <ul> <li> <a href='ar' style='background-position: 0px 0px;'>Argentina</a></li> <li> <a href='br' style='background-position: 0px −29px;'>Brazil</a></li> <li> <a href='fi' style='background-position: 0px −58px;'>Finland</a></li> <li> <a href='jp' style='background-position: 0px −87px;'>Japan</a></li> <li> <a href='es' style='background-position: 0px −116px;'>Spain</a></li> <li> <a href='us' style='background-position: 0px −145px;'>United States</a></li> </ul> </body> </html>
Для фотографий и больших файлов не рекомендуется использовать CSS-спрайты. Если у тебя на сайте изображения в формате PNG, то лучше всего иконки с похожей цветовой гаммой просто сгруппировать.
В таблице 7.14 приведена информация о совместимости CSS спрайтов с разными мобильными платформами.
Браузер/ Платформа | Спрайты для блоков (<div>) | Спрайты для ссылок (<a>) |
---|---|---|
Safari | Да | Да |
Android browser | Да | Да |
Symbian/S60 | Да | Да |
Nokia Series 40 | Да в 6-м выпуске, Нет до 6-го выпуска |
Да, бажит на low-end усройствах |
webOS | Да | Да |
BlackBerry | Да, с версии 4.0 | Да, с версии 4.0 |
NetFront | Нет | Да |
Openwave (Myriad) | Нет | Нет |
Internet Explorer | Нет | Да |
Motorola Internet Browser | Нет | Нет |
Opera Mobile | Да | Да |
Opera Mini | Да | Да |
Альтернативы CSS спрайтам
Даже если ты не хочешь использовать спрайты CSS, идея с оптимизацией количества запросов к сереверу все равно остается очень интересной и заманчивой. Поэтому для некоторых ситуаций мы должны подумать об альтернативных путях ее реализации.
Карта изображений — первый метод, который приходит на ум как альтернатива CSS спрайтам. Но, не рекомендуется использовать его для устройств без сенсорной навигации, потому как в противном случае может существенно пострадать юзабилити.
Встроенные изображения
Как мы уже говорили в предыдущей главе, встроенные изображения — это отличный метод для современных браузеров. При разработке для браузеров, которые понимают этот метод, мы можем скопировать первый наш пример (исходный документ без CSS спрайтов) и определить каждое изображение в виде data:URL.
Объединение изображений
Если, как в нашем примере, изображения расположены рядом по вертикали или горизонтали, мы можем рассмотреть вариант соединения всех изображений в одно. Все очень похоже на CSS спрайты, но здесь мы делаем изображение с одноразовым использованием фона, настраивая margin и padding так, чтобы элементы были выровнены относительно разных частей изображения. На старых устройствах с ограниченной поддержкой margin и padding этот метод может не работать или показывать некорректные результаты.
Если мы будем использовать изначальный код, но позаботимся о правильном кэшировании на сервере, то последующие страницы будут загружаться быстрее, чем при использовании CSS спрайтов, потому что сократитятся затраты времени на рендеринг. Подробнее о кэшировании мы поговорим позже (Глава 10).
Бордюры блока
Если для оформления границ прямоугольной области ты хочешь использовать CSS спрайты, то для этого есть еще и альтернативный вариант в виде CSS расширений WebKit. Сейчас мы подробно разберемся с этим вопросом.
По теме
Куда дальше
- следующая — Расширения WebKit
- предыдущая — Общие шаблоны
- содержание