Адаптивные изображения в HTML: srcset, sizes и picture

Один и тот же тег <img> может показывать разные файлы картинки в зависимости от экрана - это не магия браузера, а два разных атрибута: srcset отдаёт тот же кадр в разном разрешении (чтобы не грузить огромный файл на маленький экран), а тег <picture> умеет показывать вообще другой кадр - например, квадратную обрезку вместо широкой.

В этом уроке

  1. img, srcset и sizes
  2. picture и source

Сейчас показывается кадр из source (синий) - он побеждает, пока присутствует. Удали всю строку с <source> целиком - картинка сразу переключится на запасной img (оранжевый).

img, srcset и sizes

Атрибут srcset перечисляет несколько файлов одной и той же картинки в разных размерах через запятую, каждый с пометкой ширины в пикселях и буквой w - например, 400w для файла шириной 400 пикселей. Атрибут sizes отдельно сообщает браузеру, какую реальную ширину картинка займёт в вёрстке при разной ширине экрана - без него браузер не может правильно посчитать, какой файл из списка выбрать.

<img src="/images/koshka-800.jpg" srcset="/images/koshka-400.jpg 400w, /images/koshka-800.jpg 800w, /images/koshka-1200.jpg 1200w" sizes="(max-width: 600px) 100vw, 600px" alt="Рыжая кошка спит на подоконнике"> - три файла на выбор и честно указано, сколько места картинка займёт на странице.

<img src="/images/koshka-800.jpg" srcset="/images/koshka-400.jpg 400px, /images/koshka-800.jpg 800px" alt="Рыжая кошка спит на подоконнике"> - дескриптор должен заканчиваться на w, а не на px: с такой записью браузер не распознаёт кандидатов и просто покажет обычный src.

picture и source

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

<picture><source media="(max-width: 600px)" srcset="/images/koshka-kvadrat.jpg"><img src="/images/koshka-shirokaya.jpg" alt="Рыжая кошка на подоконнике"></picture> - есть запасной img, картинка покажется в любом случае.

<picture><source media="(max-width: 600px)" srcset="/images/koshka-kvadrat.jpg"></picture> - без img внутри: если условие не подошло (или браузер не знает picture), не покажется вообще ничего.

Из истории У задачи "разные картинки на разных экранах" изначально боролись за одно решение, а получилось два. В мае 2012 года, когда Ian Hickson (редактор спецификации WHATWG) попросил рабочую группу Responsive Images Community Group предложить конкретный синтаксис, Theresa O'Connor из Apple предложила srcset - для того же кадра в разном разрешении. Отдельно Mat Marquis и RICG отстаивали picture - для художественного кадрирования, когда нужен другой кадр, а не просто файл полегче. 18 июня 2012 года Florian Rivoal предложил не выбирать одно решение, а оставить оба - для двух разных задач. Так в HTML появились сразу два механизма вместо одного.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Писать дескриптор ширины как "400px" вместо "400w" в srcset Браузер не распознаёт кандидатов, srcset не срабатывает, показывается обычный src Всегда заканчивать дескриптор буквой w: "400w", "800w"
Использовать w-дескрипторы в srcset без атрибута sizes Браузер считает, что картинка займёт всю ширину экрана, и может выбрать файл крупнее, чем нужно на самом деле Указывать sizes с реальной шириной, которую картинка займёт в вёрстке
Оставлять source внутри picture без запасного img Если ни одно условие source не подошло (или браузер не поддерживает picture) - не покажется вообще ничего Всегда добавлять img последним элементом внутри picture
Использовать srcset там, где на самом деле нужен другой кадр, а не просто разрешение полегче На широком экране просто увеличится тот же кадр вместо показа другой, более уместной композиции Для разных кадров (art direction) нужен picture с source, а не srcset у обычного img

Шпаргалка

ТерминЗначение
srcsetСписок файлов того же кадра в разных размерах с дескриптором ширины (например, 400w)
sizesРеальная ширина, которую картинка займёт в вёрстке - нужен для работы w-дескрипторов
pictureКонтейнер с несколькими вариантами картинки и обязательным запасным img внутри
sourceВариант картинки внутри picture с условием media (или форматом type)

Коротко: отвечаем на вопросы

Что будет, если у img со srcset (через w-дескрипторы) не указать sizes?

По умолчанию браузер посчитает, что картинка займёт всю ширину экрана - sizes="100vw". Если на самом деле картинка в вёрстке занимает меньше места, браузер может выбрать файл крупнее, чем реально нужно, и скачать лишние килобайты зря.

Обязательно ли добавлять img внутри picture?

Да, обязательно, и именно последним элементом. Он служит запасным вариантом сразу для двух случаев: когда ни одно условие media у source не подошло, и когда браузер вообще не поддерживает picture - тогда он просто покажет img и проигнорирует незнакомые ему source.

Чем srcset у обычного img отличается от picture - когда что использовать?

srcset у img - это переключение разрешения: браузер сам выбирает файл того же кадра, подходящий по размеру экрана. picture нужен для другой задачи - художественного кадрирования, когда на разных экранах должен показываться не просто более лёгкий файл, а другая композиция кадра (например, квадратная обрезка вместо широкой).

Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×