Pull to refresh

Bootstrap CSS Sprite: синтаксический сахар для <img />

Website development *PHP *Yii *

UPD


Сегодня в этом уже нет никакого смысла. Просто настройте себе HTTP/2



Что это?


В один прекрасный день я отчётливо понял, что устал писать длинные ссылки на файлы изображений, каждый раз задавать им ширину и высоту, заботиться о том, чтобы это всё не прыгало при загрузке и не мигало при наведении мышкой. И я решил автоматизировать всю эту рутину. Так появился Bootstrap CSS Sprite — библиотека, которая позволяет работать со всеми вашими изображениями, как с одним спрайтом. При этом доступ к тайлам спрайта осуществляется в стиле Twitter Bootstrap.

Приведу пример: у нас есть файл изображения cat.png. Чтобы показать это изображение надо использовать тег <i>, указав для него CSS-класс img-cat, как мы делаем это в Twitter Bootstrap:

<i class="img-cat"></i>



Преимущества


  • Вместо множества файлов с изображениями мы получаем один и, как следствие, всего один запрос к серверу вместо множества.
  • Смена изображения при первом наведении мышкой (hover) без мигания и подёргиваний.
  • Больше нет нужды указывать ширину и высоту для каждого изображения в HTML-шаблонах — библиотека сделает это за нас в сгенерированном CSS-файле.
  • Меньше HTML-кода:
    <i class="img-cat"></i>
    
    вместо
    <img src="<?=$this->theme->baseUrl?>/images/cat.png" style="width: 64px; height: 64px;" />
    

    Думаю, это будет действительно экономить время!


Как использовать


Давайте рассмотрим самый простой способ использования библиотеки. Для генерации спрайта надо указать, где и какие файлы надо брать. В нашем случае берём jpg, jpeg, gif и png из директории /path/to/images/source. Затем указываем путь к файлу спрайта — /path/to/images/sprite.png — в него будут объединены все исходные изображения. Также будет сгенерирован CSS-файл — /path/to/css/sprite.css, который содержит классы для всех обработанных изображений. Эти классы определяют ссылку на изображение, его размеры, а также поведение при наведении мышкой.
$sprite = new BootstrapCssSprite(array(
    'imgSourcePath' => '/path/to/images/source',
    'imgSourceExt'  => 'jpg,jpeg,gif,png',
    'imgDestPath'   => '/path/to/images/sprite.png',
    'cssPath'       => '/path/to/css/sprite.css',
    'cssImgUrl'     => '/url/to/images/sprite.png',
));
$sprite->generate();
Генерацию надо запускать только при добавлении новых изображений.

Также уже готова реализация в виде компонента для Yii Framework. Работа с ним будет полностью аналогична. Надо просто скопировать файл YiiBootstrapCssSprite.php в /extensions/ и добавить его в конфиг:
'components' => array(
    ...
    'sprite' => array(
        'class'         => 'ext.YiiBootstrapCssSprite',
        'imgSourcePath' => '/path/to/images/source',
        'imgSourceExt'  => 'jpg,jpeg,gif,png',
        'imgDestPath'   => '/path/to/images/sprite.png',
        'cssPath'       => '/path/to/css/sprite.css',
        'cssImgUrl'     => '/url/to/images/sprite.png',
    ),
    ...
)
После чего генерируем спрайт:
abstract class BaseController
{
    public function init()
    {
        ...
        if (APP_ENV === APP_ENV_DEV) {
            Yii::app()->sprite->generate(); // Regenerates sprite only if source dir was changed
        }
        ...
    }
}


:hover


Для того, чтобы менять картинку при наведении мышкой, достаточно всего лишь положить файл изображения cat.hover.png рядом с cat.png. И это всё! Если же надо изменять картинку при наведении мышкой на её родительский элемент (а не на саму картинку), тогда придётся попотеть и добавить CSS-класс hover-img к этому элементу:
<button class="btn hover-img"><i class="img-cat"></i> My Cat</button>

Также есть возможность вручную эмулировать событие наведения:
$('.img-cat').addClass('hover');


Планы на будущее


Планов по развитию довольно много. Из основного:
  • Реализовать генерацию спрайта с использованием разных графических библиотек (сейчас есть реализация только с GD lib).
  • Оформить библиотеку в виде компонента (бандла, etc.) для основных PHP-фреймворков (Yii, Zend, Symfony).
  • Портировать библиотеку на другие веб-ориентированные языки (Ruby, Python, .Net, Java, etc.).

Надеюсь, что после публикации статьи, планы на будущее значительно расширятся, а радость веб-разработчиков всех стран и народов повысится. Жду ваших комментариев и пулл реквестов :)

UPD maximw высказал хорошую идею: заменить тег <i> на <div>. Можно будет сделать этот тег конфигурируемой опцией. А @SelenIT2 дал очень дельное уточнение о том, что заменить лучше не на <div>, а на <span>, дабы не порвать DOM при вставке в строчные элементы.
Tags:
Hubs:
Total votes 22: ↑14 and ↓8 +6
Views 21K
Comments Comments 62