Доводилось ли вам сталкиваться с ситуацией, когда картинка на вашем сайте и ее размеры должны меняться в зависимости от устройства или ширины экрана? Однозначно да! Однако обилие девайсов для просмотра веба в наше время увеличивается в такой прогрессии, что можно легко запутаться с задачей - где, что и как показывать.

Казалось бы, эту проблему довольно легко решить с помощью CSS-свойства background-image и медиа-запросов в стилях. Но что, если нам нужен именно тег img (для семантики или SEO-требований). Давным-давно использовали супер-нерациональный подход - вставлять в код HTML несколько тегов img (например, с картинкой для десктопа и для мобилки) и скрывать их теми же стилями по соответствующим медиа-запросам. Позже, отслеживали тип девайса и опираясь на него подгружали нужную картинку. Однако представьте, что нам нужно предусмотреть все варианты картинок здесь и сейчас, да чтобы для соответствующего девайса грузилась нужная и без утяжеляющих скриптов, следящих за размером экрана. Все это решается атрибутами srcset и sizes.

Как браузер подготавливает картинки

На большинстве веб-сайтов изображения являются самыми тяжелыми элементами и должны начинать (и заканчивать) загрузку раньше всего остального. Поэтому работа браузеров начинается со сканирования HTML веб-страницы на предмет URL-адресов изображений и их загрузки. Это происходит до того, как браузер создает DOM, собирает макет или загружает внешний CSS. Следовательно, браузеру необходимо знать источник изображения еще до того, как он определит размер отрисованного изображения.

Также стоит понимать, что браузер автоматически знает среды, в которых отображаются все веб-элементы: размер области просмотра, разрешение экрана пользователя и т. д. Эти данные используются для определения медиа-запросов. И этими данными как раз и стоит пользоваться для настройки подгрузки соответствующих изображений на сайте.

Все, что вам необходимо для работы - предоставленный от дизайнеров сет картинок с разным качеством и, если необходимо, размерами. Оптимальное решение такой комплексной задачи может уместиться всего в одном HTML-теге img.

Как подгружать разные картинки

Если необходимо загружать соответствующий вариант картинки в зависимости от плотности пикселей устройства, мы можем использовать атрибут srcset. Делается это подобным образом:

<img srcset="image.jpg, image@2x.jpg 2x, image@3x.jpg 3x" />

x в значении атрибута является дескриптором плотности пикселей, который указывает браузеру - какую картинку необходимо подгружать для девайса, на котором будет просматриваться ваша страница. Так, на мобильном устройстве с двойной плотностью пикселей загрузится картинка image@2x.jpg.

Если необходимо выбрать картинку на основе фактической ширины, необходимой для ее отображения, следует применить дескриптор ширины w.

<img srcset="img-small.jpg 480w, img-medium.jpg 768w, img-large.jpg 1024w" />

Что делает этот подход - сообщает браузеру ширину каждого изображения, чтобы браузеру не приходилось загружать их заранее. Когда браузер знает, что изображения размером максимум 480px достаточно, он загрузит только его. В противном случае он возьмет большее. Важно понимать, что при расчете требуемой ширины браузер также учитывает плотность пикселей дисплея. Например, если изображение занимает всю область просмотра окна и мы его смотрим на экране мобильного устройства 375px с плотностью 2x, браузер выберет картинку img-medium.jpg, т.к. ему нужна картинка шириной 375*2 = 750px.

В дополнение стоит отметить, что в данном коде всегда нужно добавлять обычный атрибут src со ссылкой на изображение по умолчанию. Это резервный механизм для случаев, если браузеры не поддерживают srcset.

<img src="img-default.jpg" srcset="img-small.jpg 480w, img-medium.jpg 768w, img-large.jpg 1024w" />

Как управлять размером картинок

Чтобы указать браузеру еще и размер картинки для определенной ширины его окна, необходимо использовать второй атрибут - sizes.

<img
  src="img-default.jpg"
  srcset="img-small.jpg 480w, img-large.jpg 1200w"
  sizes="(max-width: 480px) 100%, (max-width: 1200px) 50%, 800px"
/>

Данная запись сообщает браузеру - насколько большое изображение должно отображаться для каждого медиа-запроса, и расшифровывается следующим образом:

  • (max-width: 480px) 100%: для окна меньше 480px ширина изображения будет 100%;
  • (max-width: 1200px) 50%: для размера окна в пределах 480px и 1200px ширина изображения будет 50%;
  • 800px: для окна шире 1200px ширина картинки будет 800px.

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