Адаптивные изображения. Атрибут srcset. Тег picture.

Адаптивные изображения. Атрибут srcset. Тег picture.

Maksym Pohribniak

При верстке веб-страниц често приходится решать следующую задачу:

Пример адаптивного изображения

На разных типах устройств используются разные изображения. Мы не просто адаптируем размер, а отображаем различные картинки (с разными размерами и весом) в зависимости от размеров, типа и ориентации устройства.

Еще примеры:

Используем различные фоновые изображения
Разный логотип в зависимости от устройства

Одно из решений – использовать медиа запросы, и показывать только те изображения, которые совпадают с @media условием. К слову, это самый распространенный подход. Однако, в данном случае браузер скачает все доступные ему изображения, даже те, которые пользователь никогда не увидит.

Мы можем использовать JavaScript, определять размер экрана и загружать только нужное изображение. Но и такой метод не без изъянов. Мы не будем загружать лишние ресурсы, но нам потребуется больше времени на показ изображения. Из-за того, что скрипты у нас выполняются после стадии layout и paint, пользователь явно увидит появление картинки на экране с задержкой.

Однако есть решение намного лучше – дать браузеру самому решать какое изображение лучше подходит для текущей ситуации. Он сам проанализирует это исходя из того, что он знает об данном устройстве, а нам всего лишь нужно использовать уже имеющийся функционал.

Атрибут srcset у <img>

Список из одного или нескольких значений, разделённых запятыми, указывающих набор возможных изображений для отображения в браузере. Каждая строка может состоять их следующих частей:

  • адрес изображения;
  • дескриптор ширины, который представляет собой целое положительное число, за которым следует w (например: 600w);
  • дескриптор плотности пикселей, представляет собой положительное десятичное число, за которым сразу следует х.

Правда есть одно замечание – нельзя использовать w и x дескрипторы вместе: придется выбрать что-то одно. Песочница по ссылке.

Форма записи следующая:

Набор изображений с указанием их размеров

Однако не все браузеры одинаково хорошо работают с этим атрибутом:
Chrome не загрузит версию изображения на Retina, если доступна версия. 
Так же, Chrome старается показать наибольшее изображение из доступных и при уменьшении экрана картинка изменятся не будет. Хотя в обратном случае (открыть страницу с небольшой шариной, и увеличивать) все сработвет как надо.

Дело в том, что, как только ваш браузер получает изображение с более высоким разрешением (загружено, в кеше), для него нет смысла загружать изображение более низкого качества, даже когда вы уменьшаете размер окна (суть в том, чтобы сэкономить трафик).

Firefox не загрузит версию изображения динамически при уменьшении экрана и последующем увеличении. Прямо как Chrome только наоборот, браузер будет использовать версию изображения. Тем не менее, при обновлении страницы загрузится необходимая версия изображения для любого размера. Мы можем добавить шибкости этому подходу добавив следующий атрибут.

Атрибут sizes у <img>

Определяет перечень медиа-выражений (например, ширину экрана) и указывает предпочтительную ширину изображения, когда определённое медиа-выражение истинно. Песочница по ссылке.

С такими атрибутами, браузер сделает следующее:

  1. Посмотрит на ширину экрана устройства.
  2. Попытается определить подходящее медиа-условие из списка в атрибуте sizes.
  3. Посмотрит на размер слота к этому медиа-запросу.
  4. Загрузит наиболее подходящее изображение руководствуясь списком из srcset

Атрибуты srcset и sizes кажутся сложными, но они не так плохи, если вы отформатируете их как в примере выше: каждая часть значения атрибута с новой строки. Хоть это и не избавляет от возможных ошибок в столь сложном синтаксисе.

Однако, мы можем сделать еще лучше!
Добавить читабельности и избавится от выше описанных проблем поможет тег <picture> .

Тег picture

служит контейнером для одного или более элементов <source> и одного элемента <img> для обеспечения оптимальной версии изображения для различных размеров экрана. Браузер рассмотрит каждый из дочерних элементов  <source> и выберет один, соответствующий лучшему совпадению; если совпадений среди элементов <source> найдено не будет, то будет выбран файл, указанный атрибутом  src элемента <img> . Затем выбранное изображение отображается в пространстве, занятом элементом <img>

Код выше переписан с использованием picture

Песочница по ссылке.

Браузер анализирует атрибуты srcsetmedia, type элемента <source> и выбирает совместимое изображение, которое наилучшим образом соответствует текущему макету.

Кейсы которые покрывает данный тег:

  • для экранов ретина можно показывать картинку большего размера;
  • выводить рисунки разного размера для мобильных и настольных устройств;
  • отображать изображения разных пропорций, учитывающих ориентацию устройства;
  • выводить изображение в векторном формате SVG, а для браузеров, его не поддерживающих, показывать PNG.


Report Page