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
- предыдущая — Общие шаблоны
- содержание
