Адаптивные изображения. Лучший способ понравиться мобилке.

Адаптивные изображения

Самый простой вариант "адаптировать" картинку - задать ширину 100% а высоту рассчитывать автоматически. Наше изображение никогда не будет шире родительского блока, при этом браузер будет ресайзить его с сохранением пропорций. Недостаток этого способа в том что и мобилке и дэсктопу отдаётся одна и таже, большая картинка. Будет лучше если на смартфон будет отправлена картинка меньшего размера. Таким образом мы экономим трафик посетителю и ускоряем загрузку страницы.

Тег <picture>

За адаптивность переживают не только разработчики сайтов но и разработчики браузеров. Как итог мы имеем тег <pictures>, который был предложен в 2011 году, как вариант тега <video> только с изображениями. Окончательно определились со спецификацией в 2014 и на данный момент <pictures> поддерживается в Chrome Opera и Firefox.
Главное что нужно запомнить - тег <pictures> не работает без <img>. По сути это обёртка для тега <img> расширяющая его возможности. Иногда можно обойтись и без <picture> используя сокращённую запись. Что же такого интересного нам может предложить новый тег?

Главный недостаток тега <img> - только один атрибут src и следовательно одна картинка для всех экранов. Тег <picture> решает эту проблему. Рассмотрим пример

<img
  src="image.jpg"
  srcset="image.jpg 300w,
          medium_image.jpg 650w,
          large_image.jpg 1000w"
  sizes="(min-width: 600px) 50vw, 100vw"
>

Первым атрибутом идёт обязательный атрибут src. Далее новый атрибут srcset, в котором перечисляются доступные изображения и их размер. Запись large_image.jpg 1000w означает что есть картинка large_image.jpg шириной 1000px. В атрибуте sizes перечисляются медиа-выражения для контрольных точек и соответствующие им размеры изображений. Размер указывается в vw(viewport width) - проценты от ширины окна.

Теперь о том как всё это работает. Предположим у нас браузер с шириной окна 900px. По правилу установленному в атрибуте sizes размер изображения будет 50% от 900px = 450px. Далее браузер выбирает лучший вариант из доступных. В нашем случае это будет medium_image.jpg.

В примере выше мы показываем браузеру возможные варианты оставляя за ним право выбора. Чтобы однозначно указать браузеру какое изображение показывать используем следующий код

<picture>
  <source media="(min-width: 600px)" srcset="medium_image.jpg">
  <source media="(min-width: 1024px)" srcset="large_image.jpg">
  <img src="image.jpg">
</picture>

Похоже на то, как задавать контрольные точки в адаптивной вёрстке. В атрибуте media элемента <source> мы определяем ширину окна, а в srcset соответственное изображение. Изображение из <img> пойдёт для браузеров не поддерживающих тег <pictures>.

Ещё один способ сберечь трафик посетителей - использовать изображения в формате WebP. Формат разработан в Google. Размер файла с изображением в формате WebP по сравнению с jpeg меньше на 25%. Проблема в том, что не все браузеры поддерживают этот формат. Новый элемент<picture> умеет отдавать браузерам только те картинки которые они могут отобразить. Для этого у элемента <source> в атрибуте type указываем формат изображения. Не забываем стандартный <img>, для тех кто не дружит с новыми форматами.

<picture>
  <source type="image/webp" srcset="image.webp">
  <img src="image.jpg">
</picture> 

Тег <picture> поддерживается в Chrome и других браузерах на движке blink. В FireFox на данный момент(FireFox 36) поддержку нужно включать в настройках, а IE и Safari вообще ничего не знают о новом элементе. Не лучше обстоят дела с мобильными браузерами. Обычное дело для нового тега. Обеспечить поддержку для <picture> и соответствующих функций в браузерах, которые еще не поддерживают их, можно с помощью полифила Picturefill http://scottjehl.github.io/picturefill/.

Adaptive Images

Adaptive Images интересное решение учитывая простоту установки и отсутствие заморочек с изменением разметки. Определяет размер экрана посетителя и вставляет на страницу нужное изображение.

В установке нет ничего сложного. Скачиваем дистрибутив с сайта http://adaptive-images.com/. Копируем файлы adaptive-images.php и .htaccess в корень сайта. Скорее всего в корне уже лежит файл .htaccess. В этом случае отредактируйте его но прежде сделайте копию на всякий случай. Если в вашем .htaccess файле есть раздел который начинается с


<IfModule mod_rewrite.c>

вставьте в этот раздел то, что содержится между # Adaptive-Images и # END Adaptive-Images. Если же такого раздела нет, то скопируйте содержимое целиком.
В раздел <head> нужно вставить следующий JS код


<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>

Этот код должен загружаться раньше других скриптов.
Последний шаг - конфигурация файла adaptive-images.php. В переменной $resolution - указывается ширина экранов. Как правило задаются размеры указанные в медиа-запросах в CSS. $cashe_path путь к папке куда будут складываться изменённые изображения.

Теперь о том как всё это работает. Размер окна посетителя определяется JavaScript размещённом в разделе <head>. Эта информация записывается в куки. Когда браузер встречает на странице тег <img> и отправляет запрос на сервер чтобы получить изображение он отправляет куки. Веб-сервер Apache получив запрос на изображение смотрит есть ли у него какие нибудь специальные инструкции для файлов. В .htaccess у нас есть правило по которому сервер любой запрос на jpg, png или gif отправляет в adaptive-images.php. PHP файл ищет куки и узнаёт какой размер экрана. Дальше происходит сравнение значения из куки со значениями прописанными в переменной $resolution и выбирается лучшее значение. Предположим было выбрано значение 480px. Отресайзенная картинка должна находиться в папке /ai-cashe/480/. Если её там нет то будет запрошен исходный файл и если его ширина будет меньше ширины экрана то по посетителю отдадут исходный файл. Если размер больше, то файл уменьшается до нужного размера и посылается пользователю. Изменённая копия сохраняется, чтобы в следующий раз не ресайзить.

Ещё пара способов сделать адаптивные изображения

Проблема адаптивных изображений уже давно занимает умы верстальщиков и имеет множество решений. Самый простой вариант - замена значения атрибута src тега <img> при помощи JavaScript. Ещё один способ поставить большую картинку как фон для блока а маленькую прописать в теге <img>(подробнее здесь http://csswizardry.com/2011/07/responsive-images-right-now/).

Просматривая возможные решения я обратил внимание что все они были предложены до элемента <picture>. Этот новый элемент предлагает лучший вариант решения проблемы адаптивных картинок.

Adaptive Image - простой в настройке. Это хорошая альтернатива если нет желания заморачиваться с кучей файлов, создавая по три файла на каждую картинку. Хотя этот плюс может обратиться в минус. Часто уменьшая большие фотографии в конечном итоге лучше вырезать какую-то часть чем просто отресайзить. Ещё один минус Adaptive Image - нагрузка на сервер.

Кстати, если ваш на сайт работает на Drupal в следующей статье попробуем внедрить <pictures> и максимально автоматизировать процесс ресайза картинок.

Хорошие способы, особенно первый: достаточно просто ) Чувствую, что скоро все-таки доберусь до своего шаблона, надо делать мобильную версию.

Олег, картинки в этой статье не отображаются почему-то.