Атрибут 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.
Дескриптор может быть двух типов:
- Физическая ширина картинки в пикселях (actual width). Например
600w,1000w - Плотность пикселей устройства (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до300px600x300.pngесли ширина экрана от300pxдо600px1000x500.pngесли ширина экрана от600pxдо1000px2000x1000.pngесли ширина экрана от1000pxдо2000px3000x1500.pngесли ширина экрана от2000pxдо3000px
Если у вашего устройства DPR=2 (подходящая картинка будет в 2 раза больше её физической ширины):
600x300.pngесли ширина экрана от0pxдо300px2000x1000.pngесли ширина экрана от300pxдо600px2000x1000.pngесли ширина экрана от600pxдо1000px3000x1500.pngесли ширина экрана от1000pxдо2000px3000x1500.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=12000x1000.pngеслиDPR=23000x1500.pngеслиDPR=3
Выбор размера картинки Sizes
Когда изображение занимает лишь часть ширины экрана. srcset без sizes будет недостаточно. Поскольку браузер ничего не знает о лейоуте (как выглядит страница), он будет считать, что картинка занимает всю ширину экрана. Но если картинка занимает лишь часть, то в результате будет загружено большее чем нужно изображение.
Логично предположить, что у браузера есть css стили и он может узнать какая ширина в итоге будет у картинки. Но, на момент парсинга тега IMG css стили еще не интерпертированы, макет (лейоут) еще не нарисован. Если браузер будет ждать, пока все таблицы стилей будут разобраны и выполнены, это приведет к задержке загрузки изображений.
Если для картинки не указаны никакие размеры в css, то sizes также ограничит размер картинки, как это делает атрибут width.
Если для картинки указать, css свойство max-width:100%, то это свойство перебивает значение атрибута sizes т.е. если ширина картинки по sizes больше ширины элемента в котором она расположена — её ширина будет равна ширине элемента max-width:100%. В общем, все также как и для стандартных width и height атрибутов.
Элементы в sizes могут иметь:
Медиа условиенапример,max-width: 300pxописывает ширину области просмотра.max-width: 300pxозначает, что указанный размер подходит для ширины экрана от0pxдо300px(включительно). Это похоже на медиа-запрос, но с некоторыми ограничениями. Вы не можете использоватьscreenилиprintШирина картинкидля указанного медиа условия. Для указания ширины можно использовать все велечины, только кроме%
При таком раскладе, следующий код:
<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>
Инструкции расшифровываются так:
(max-width: 350px) 150pxпри ширине меньше350pxподставить изображение, ближайшее к150px(max-width: 600px) 300pxпри ширине меньше600pxподставить изображение, ближайшее к300px(max-width: 1400px) 500pxпри ширине меньше1400pxподставить изображение, ближайшее к500px1000pxво всех остальных случаях подставить изображение, ближайшее к1000px
Нужно помнить об экранах с ретиной. Целевые размеры изображения приводятся к ЦСС‑пикселям — это означает, что на экране с ретиной браузер постарается подставить изображение с удвоенным разрешением.
С sizes
Без sizes
