Адаптивные изображения. Что использовать: img или picture?
Теги img
и picture
предназначены для загрузки изображений. Каждый из них позволяет задать набор правил, согласно которым браузер будет выбирать, какое из изображений загружать. Рассмотрим синтаксис и различия данных тегов. Для начала нужно задать следующий метатег:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Данный метатег указывает браузеру выполнять масштабирование размеров экрана устройства. Так, например, размеры экрана iPhone X составляют 375x812 css-пикселей.
Для тестирования будем использовать следующее изображение:
Тег img
Атрибут srcset
предназначен для указания всех доступных размеров изображений и URL каждого из них. При этом, тег src
указывать нужно. Его значение будет использовано, если все варианты из srcset
не подойдут согласно указанным правилам.
Атрибут srcset
содержит список из одной или нескольких строк, разделённых запятыми, указывающих набор источников изображения. Каждая строка состоит из:
URL изображения.
Дескриптора ширины.
Рассмотрим на примере:
<img
src="bears-1920x1080.jpg"
alt="bears"
srcset="
bears-480x270.jpg 480w,
bears-960x540.jpg 960w,
bears-1920x1080.jpg 1920w
"
/>
Ширина всех доступных изображений указывается в пикселях. По историческим причинам для обозначения пикселей используется символ w
. В данном примере атрибут srcset
содержит три изображения, ширина которых 480, 960 и 1920 пикселей соответственно. Браузер выберет изображение в зависимости от ширины экрана устройтва и его плотности пикселей. Если ширина экрана не превышает 480 css-пикселей, то будет выбрано следующее изображение:
bears-480x270.jpg
, если коэфициент плотности пикселей равен 1.bears-960x540.jpg
, если коэфициент плотности пикселей равен 2 (retina display).bears-1920x1080.jpg
, если коэфициент плотности пикселей больше 2.
Аналогично, если ширина экрана больше 480 css-пикселей, но не превышает 960 css-пикселей, то:
bears-960x540.jpg
, если коэфициент плотности пикселей равен 1.bears-1920x1080.jpg
, если коэфициент плотности пикселей больше или равен 2.
При этом браузер будет подразумевать, что изображение занимает всю ширину экрана. Для переопределения такого поведения предназначен атрибут sizes
, который содержит список из одной или нескольких строк, разделённых запятыми, указывающих какую максимальную ширину может занимать изображение при определённом размере экрана. Каждая строка состоит из:
Ширины изображения.
Рассмотрим на примере:
<img
src="bears-1920x1080.jpg"
alt="bears"
sizes="(max-width: 600px) 480px, (max-width: 1200px) 960px, 100vw"
srcset="
bears-480x270.jpg 480w,
bears-960x540.jpg 960w,
bears-1920x1080.jpg 1920w
"
/>
В данном примере браузер будет следовать следующим правилам при выборе источника изображения:
Если ширина экрана устройства составляет не более 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.
Если ширина экрана устройства составляет от 600 до 1200 css-пикселей, то изображение на таком экране занимает максимум 960 css-пикселей в ширину.
В противном случае браузер будет подразумевать, что изображение может занимает всю ширину экрана.
Также нужно учитывать коэфициент плотности пикселей. Например, если ширина экрана устройства составляет 550 css-пикселей, то браузер выберет следующее изображение:
bears-480x270.jpg
, если коэфициент плотности пикселей равен 1. Так как ширина экрана устройства не превышает 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.bears-960x540.jpg
, если коэфициент плотности пикселей равен 2.bears-1920x1080.jpg
, если коэфициент плотности пикселей больше 2.
Атрибут sizes
нужно указывать, если размеры изображения ограничены css стилями. Если атрибут sizes
не указан, то по умолчанию он будет иметь значение 100vw
(sizes="100vw"
), то есть браузер будет подразумевать, что изображение может занимает всю ширину экрана.
Тег picture
Тег picture
служит контейнером для одного или более тегов source
и одного тега img
. Тег source
представляет собой источник изображения. Он содержит информацию о формате изображения и его размерах, а также правила, при соблюдении которых браузер должен выбрать этот источник. Если все источники не подходят, то будет выбран файл, указанный в атрибуте src
тега img
. Если сразу несколько источников подходят, то браузер выберет первый по порядку.
Тег source
имеет атрибуты sizes
и srcset
. Они работают также, как и соотвествующие атрибуты у тега img
. Рассмотрим на примере:
<picture>
<source
srcset="bears-480x270.jpg 480w, bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
sizes="(max-width: 600px) 480px, (max-width: 1200px) 960px, 100vw"
/>
<img src="bears-1920x1080.jpg" alt="bears" />
</picture>
Данный пример работает так же, как и второй пример использования тега img
.
Разница между img и picture
Тег picture
позволяет указать браузеру использовать разные изображения в зависимости от размера экрана. Достигается это за счёт использования атрибута media
тега source
, который позволяет задать медиа выражение, при котором будет использоваться данный источник. Например, на маленьких экранах мы хотим использовать обрезанное изображение cropped-bears.jpg
, которое содержит основную часть изображения:
Для этого нужно указать несколько тегов source
и задать им атрибуты media
:
<picture>
<source
media="(max-width: 480px)"
srcset="
cropped-bears-480x270.jpg 480w,
cropped-bears-960x540.jpg 960w
"
/>
<source
media="(max-width: 960px)"
srcset="bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
/>
<img src="bears-1920x1080.jpg" alt="bears" />
</picture>
В данном примере, если ширина экрана устройства не превышает 480 css-пикселей, то будет выбрано обрезанное изображение. Добиться такого результата при помощи тега img
не получиться, так как изображения cropped-bears-960x540.jpg
и bears-960x540.jpg
имеют одинаковый размер, но изображение cropped-bears-960x540.jpg
предназначено для использования на устройстве, ширина которого не превышает 480 css-пикселей и коэфициент плотности пикселей равен 2, а изображение bears-960x540.jpg
- на устройстве, ширина которого от 480 до 960 css-пикселей и коэфициент плотности пикселей равен 1.
Также, тег picture
позволяет указать различные форматы изображения, например webp
и jpeg
. Для этого нужно тегу source
задать атрибут type:
<picture>
<source
type="image/webp"
media="(max-width: 480px)"
srcset="
cropped-bears-480x270.webp 480w,
cropped-bears-960x540.webp 960w
"
/>
<source
type="image/webp"
media="(max-width: 960px)"
srcset="bears-960x540.webp 960w, bears-1920x1080.webp 1920w"
/>
<source
type="image/jpeg"
media="(max-width: 480px)"
srcset="
cropped-bears-480x270.jpg 480w,
cropped-bears-960x540.jpg 960w
"
/>
<source
type="image/jpeg"
media="(max-width: 960px)"
srcset="bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
/>
<img src="bears-1920x1080.jpg" alt="bears" />
</picture>
Источники с наименее поддерживаемыми типами нужно располагать в начале списка, так как браузер выберет первый по порядку подходящий источник. В данном примере браузер выберет тип изображения webp
, если он его поддерживает. В противном случае будет выбран тип jpeg
.