Практическое решение: CSS Tidy. Алгоритм разбора и сбора CSS Sprites. Уменьшение количества запросов
Прикладные тонкости
Практическое решение: CSS Tidy
Практическое решение: сборка изображений
Дальше начинается самое интересное: как нам вышеописанные группы «склеивать»? Для этого используется следующий алгоритм:
1. Изображения, для которых позиционирование задано в процентах и которые находятся внутри контейнеров с абсолютными размерами, корректируются, чтобы фоновая позиция была задана в
аболютных единицах.
2. repeat-x изображения (группа 3) объединяются все вместе по вертикали. Попутно правится ширина фоновых изображений (приводится к наименьшему общему кратному). В самое начало такого файла добавляются no-repeat изображения, подходящие по ширине (группа 1). Далее в самый низ файла записывается 1 изображение из группы 4. Больше 1 все равно никуда не войдет, поскольку нам нужно обеспечить свободное пространство ниже заявленной высоты фонового изображения. Это часто бывает нужно для плавного перетекания градиента в ровный цвет: градиент вставляется фоновой картинкой, которая заканчивается на фоновом цвете, а дальше продолжается уже этот цвет, заданный через background-color.
3. Производятся абсолютно аналогичные действия с repeat-y.
4. Далее изображения из группы 7 объединяются по вертикали (0 100% означает, что фон должен быть прижат к правому краю элемента, соответственно, весь спрайт будет «прижат» к правому своему краю).
5. Аналогично с группой 8 — прижимаем все к низу. Естественно, что для всех групп мы учитываем первоначальное значение background-position.
6. Рассчитываем позиционирование для изображений группы 1 (для этого подойдет и просто перебор отсортированных по площади или сумме квадратов измерений изображений: готовим матрицу, в которую пытаемся «вписать» очередное изображение, если не получается, то матрицу увеличиваем). При вписывании ради экономии процессорного времени можно проверять только 9 точек (8 по края изображения и 1 в центре), для того чтобы убедиться, что на месте изображения еще ничего нет.
7. Строим «лесенку» из изображений второй группы. Лесенку лучше строить снизу уже созданного спрайта из предыдущего пункта: тогда легко найти минимальный размер «дырки» между двумя группами изображений, чтобы сдвинуть «лесенку» вверх (и потом, возможно влево). Конечно, поиск наиболее оптимального расположения непростая задача. Но ее можно решить и в достаточно грубом приближении, которое описано выше.
8. Изображение из пункта 3 прикрепляются к правому верхнему углу нашего сложного изображения (результат действия пунктов 5 и 6). Так как у каждого такого изображения задана допустимая высота, и все они находятся вне «рабочей» зоны остальных no-repeat изображений, то никаких рудиментов не возникнет.
9. Аналогичным образом поступаем с изображением из пункта 4 — его располагаем в нижнем левом углу нашего спрайта.
10. На выходе мы получаем 3 спрайта со всеми возможными случаями. В среднем, размеры таких спрайтов будет лишь незначительно превосходить (если вообще будет) аналогичные «ручные» аналоги (в том числе, за счет использования PNG). Естественно, что можно в автоматическом режиме пропустить через pngcrush или jpegtran. Стоит также предусмотреть, в каком виде будут создаваться полноцветные изображения: JPEG или PNG (последние больше по размеру, но гарантирует отсутствие потерь качества).
При расчете позиции картинки в конечном спрайте может помочь следующая схема:
Рис. 4.1. Схема позиционирования фоновой картинки относительно элемента.
В силу громоздкости решения (в нем более 1500 строк кода) в полном объеме в данной книге оно не приводится, однако все описанные шаги уже применены в Web Optimizer (http://www.web-optimizer.ru/) (веб-приложении для автоматизации клиентской оптимизации). Одна из финальных версий алгоритма работает для инструмента Auto Sprites (http://sprites.in/), а с исходным текстом можно ознакомиться в SVN (http://code.google.com/p/web-optimizator/source/browse/trunk/libs/php/css.sprites.php).
Эту логику можно применить на любом этапе веб-разработки (как при начальном создании дизайна, так и при пост-релизной оптимизации сайта). Библиотека для автоматического создания спрайтов распространяется по лицензии MIT (она позволяет использовать продукт где угодно и как угодно, но обязательно должна присутствовать ссылка на первоисточник, даже если используется не вся библиотека, а только ее существенная часть).