Полный цикл в digital

Атрибут srcset и sizes в CSS

Метод подходит для изображений, размер которых фиксирован на экранах повышенной плотности. Это значит, что для некоторых изображений шириной 200px, указанной в HTML, можно загрузить картинку шириной 600px или больше, так как на экране повышенной плотности она будет смотреться намного лучше.

Адаптивное изображение с помощью srcset

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

В разметку добавляем изображения с помощью тега img, который становится адаптивным с помощью обязательного атрибута srcset, и не обязательного sizes

Адаптивный img умеет:

  • Реагировать на ретину, загружать разные картинки для разной плотности пикселей
  • Реагировать на ширину вьюпорта, загружать разные картинки для разных медиавыражений
  • Работать с новыми форматами изображений

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

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

<img
srcset="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png 3x,
/upload/medialibrary/9e4/uo7fcs6cnrwlnm3enn4pwpbqgqlmd1uy/2000x1000.png 2x,
/upload/medialibrary/64a/y34avv73ojzx58y7wjok5sihuai7ifjx/1000x500.png 1x"

src="/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png"
/>

1x, 2x, 3x это идентификатор, который указывает плотность экрана для показа определённой картинки. Разработчик выбирает какие идентификаторы нужно указать для разных устройств.

Каждая строка в списке должна содержать УРЛ и дескриптор. Если никакой дескриптор не указан, то берется по умолчанию 1x.

Дескриптор может быть двух типов:

  1. Физическая ширина картинки в пикселях (actual width). Например 600w, 1000w
  2. Плотность пикселей устройства (display density) DPR (device pixel ratio), например 2x, 3x

Ваш текущий DPR можно узнать в консоли баразура, заглянув в переменную window.devicePixelRatio. Дискриптор нужен браузеру, чтобы он мог принять решение какой УРЛ из сета загружать (ведь он заранее ничего не знает о картинке которая находится в УРЛ). А с дескриптором, браузер заранее понимает какая у картинки ширина или для какого DPR она подходит.

Ваш реальный window.devicePixelRatio, выводится скриптом:

Дескриптор ширины (w — width descriptor)

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

<img
srcset="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png 3000w,
/upload/medialibrary/9e4/uo7fcs6cnrwlnm3enn4pwpbqgqlmd1uy/2000x1000.png 2000w,
/upload/medialibrary/64a/y34avv73ojzx58y7wjok5sihuai7ifjx/1000x500.png 1000w,
/upload/medialibrary/bcc/891bkjk8zssx0mdhymzj9fzf6wtgrnsi/600x300.png 600w,
/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png 300w"

src="/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png"
/>

Если у вашего устройства DPR=1:

  • 300x150.png если ширина экрана от 0px до 300px
  • 600x300.png если ширина экрана от 300px до 600px
  • 1000x500.png если ширина экрана от 600px до 1000px
  • 2000x1000.png если ширина экрана от 1000px до 2000px
  • 3000x1500.png если ширина экрана от 2000px до 3000px

Если у вашего устройства DPR=2 (подходящая картинка будет в 2 раза больше её физической ширины):

  • 600x300.png если ширина экрана от 0px до 300px
  • 2000x1000.png если ширина экрана от 300px до 600px
  • 2000x1000.png если ширина экрана от 600px до 1000px
  • 3000x1500.png если ширина экрана от 1000px до 2000px
  • 3000x1500.png если ширина экрана от 2000px до 3000px

Дескриптор размера (x — pixel density descriptor)

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

<img
srcset="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png 3x,
/upload/medialibrary/9e4/uo7fcs6cnrwlnm3enn4pwpbqgqlmd1uy/2000x1000.png 2x,
/upload/medialibrary/64a/y34avv73ojzx58y7wjok5sihuai7ifjx/1000x500.png 1x"

src="/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png"
/>

Браузер выберит картинку в зависимости от DPR

  • 1000x500.png если DPR=1
  • 2000x1000.png если DPR=2
  • 3000x1500.png если DPR=3

Выбор размера картинки Sizes

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

Логично предположить, что у браузера есть css стили и он может узнать какая ширина в итоге будет у картинки. Но, на момент парсинга тега IMG css стили еще не интерпертированы, макет (лейоут) еще не нарисован. Если браузер будет ждать, пока все таблицы стилей будут разобраны и выполнены, это приведет к задержке загрузки изображений.

Если для картинки не указаны никакие размеры в css, то sizes также ограничит размер картинки, как это делает атрибут width.

Если для картинки указать, css свойство max-width:100%, то это свойство перебивает значение атрибута sizes т.е. если ширина картинки по sizes больше ширины элемента в котором она расположена — её ширина будет равна ширине элемента max-width:100%. В общем, все также как и для стандартных width и height атрибутов.

Элементы в sizes могут иметь:

  1. Медиа условие например, max-width: 300px описывает ширину области просмотра. max-width: 300px означает, что указанный размер подходит для ширины экрана от 0px до 300px (включительно). Это похоже на медиа-запрос, но с некоторыми ограничениями. Вы не можете использовать screen или print
  2. Ширина картинки для указанного медиа условия. Для указания ширины можно использовать все велечины, только кроме %

При таком раскладе, следующий код:

<div style="width: 50%;">
<img
srcset="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png 3000w,
/upload/medialibrary/9e4/uo7fcs6cnrwlnm3enn4pwpbqgqlmd1uy/2000x1000.png 2000w,
/upload/medialibrary/64a/y34avv73ojzx58y7wjok5sihuai7ifjx/1000x500.png 1000w,
/upload/medialibrary/bcc/891bkjk8zssx0mdhymzj9fzf6wtgrnsi/600x300.png 600w,
/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png 300w"

src="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png"
/>
</div>

На ширине окна 1000 пикселей (2000 без ретины) мы покажем изображение с размерами 2000×1000 пикселей, хотя ширина области, выделенной под изображение, будет равна 500 пикселям (1000 без ретины):

2000 / 1000 = 2

Мы покажем изображение, которое в 2 раза больше, чем нужно, притом что у нас есть вариации, однозначно более подходящие для такого случая.

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

<div style="width: 50%;">
<img
srcset="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png 3000w,
/upload/medialibrary/9e4/uo7fcs6cnrwlnm3enn4pwpbqgqlmd1uy/2000x1000.png 2000w,
/upload/medialibrary/64a/y34avv73ojzx58y7wjok5sihuai7ifjx/1000x500.png 1000w,
/upload/medialibrary/bcc/891bkjk8zssx0mdhymzj9fzf6wtgrnsi/600x300.png 600w,
/upload/medialibrary/0c1/9xx7drzd9bzv8cdyljhtwqyhs1trw4vp/300x150.png 300w"

sizes="(max-width: 350px) 150px,
(max-width: 600px) 300px,
(max-width: 1400px) 500px,
1000px"

src="/upload/medialibrary/8b0/s0qymhi13cvn12drkcf560psk04x54ni/3000x1500.png"
/>
</div>

Инструкции расшифровываются так:

  1. (max-width: 350px) 150px при ширине меньше 350px подставить изображение, ближайшее к 150px
  2. (max-width: 600px) 300px при ширине меньше 600px подставить изображение, ближайшее к 300px
  3. (max-width: 1400px) 500px при ширине меньше 1400px подставить изображение, ближайшее к 500px
  4. 1000px во всех остальных случаях подставить изображение, ближайшее к 1000px

Нужно помнить об экранах с ретиной. Целевые размеры изображения приводятся к ЦСС‑пикселям — это означает, что на экране с ретиной браузер постарается подставить изображение с удвоенным разрешением.

С sizes

Без sizes

Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!