Pull to refresh

Адаптивные изображения. Что использовать: img или picture?

Reading time5 min
Views16K

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

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Данный метатег указывает браузеру выполнять масштабирование размеров экрана устройства. Так, например, размеры экрана iPhone X составляют 375x812 css-пикселей.

Для тестирования будем использовать следующее изображение:

Медведи
Медведи

Тег img

Атрибут srcset предназначен для указания всех доступных размеров изображений и URL каждого из них. При этом, тег src указывать нужно. Его значение будет использовано, если все варианты из srcset не подойдут согласно указанным правилам.

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

  1. URL изображения.

  2. Дескриптора ширины.

Рассмотрим на примере:

<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-пикселей, то будет выбрано следующее изображение:

  1. bears-480x270.jpg, если коэфициент плотности пикселей равен 1.

  2. bears-960x540.jpg, если коэфициент плотности пикселей равен 2 (retina display).

  3. bears-1920x1080.jpg, если коэфициент плотности пикселей больше 2.

Аналогично, если ширина экрана больше 480 css-пикселей, но не превышает 960 css-пикселей, то:

  1. bears-960x540.jpg, если коэфициент плотности пикселей равен 1.

  2. bears-1920x1080.jpg, если коэфициент плотности пикселей больше или равен 2.

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

  1. Медиа выражения.

  2. Ширины изображения.

Рассмотрим на примере:

<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
  "
/>

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

  1. Если ширина экрана устройства составляет не более 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.

  2. Если ширина экрана устройства составляет от 600 до 1200 css-пикселей, то изображение на таком экране занимает максимум 960 css-пикселей в ширину.

  3. В противном случае браузер будет подразумевать, что изображение может занимает всю ширину экрана.

Также нужно учитывать коэфициент плотности пикселей. Например, если ширина экрана устройства составляет 550 css-пикселей, то браузер выберет следующее изображение:

  1. bears-480x270.jpg, если коэфициент плотности пикселей равен 1. Так как ширина экрана устройства не превышает 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.

  2. bears-960x540.jpg, если коэфициент плотности пикселей равен 2.

  3. 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.

Tags:
Hubs:
Total votes 12: ↑12 and ↓0+12
Comments11

Articles