Решил добавить старенькую статью про адаптивные изображения и использование srcset, т.к. это по прежнему актуально.
Содержание
Что такое адаптивное изображение?
Проще говоря, адаптивное изображение — это изображение, которое отображается в оптимальном виде на веб-странице в зависимости от устройства, с которого просматривается ваш сайт. Термин «оптимальный вид» может означать несколько вещей:
- Вы хотите отображать отдельный ресурс с изображением в зависимости от размера физического экрана пользователя. Например, вы хотите отображать отдельный ресурс с изображением на 13,5-дюймовом ноутбуке и 5-дюймовом мобильном телефоне (в браузере с максимальным расширением).
- Вы хотите отобразить отдельное изображение в зависимости от разрешения устройства (или соотношения пикселей устройства и CSS-пикселей).
- Вы хотите отобразить изображение в указанном формате (например, JPEG XR), если браузер его поддерживает, вероятно, из-за более высокой степени сжатия, которую поддерживает этот формат.
Базовые элементы для адаптивного дизайна включены в большинство современных браузеров, включая Microsoft Edge (начиная с Windows Insider Build 10547).
Как включить адаптивные изображения
Существует несколько способов включить адаптивное поведение изображений. Один из старых методов (не рекомендуется) - с помощью простых сценариев, но это приводит к паре проблем. Во-первых, если скрипт определяет, какое изображение загружать, но сам скрипт загружается после загрузки изображений, указанных в HTML, потенциально у вас может получиться два загруженных изображения. Во-вторых, если вы не укажете никакого изображения в HTML и хотите загрузить только изображение, определенное скриптом, в конечном итоге у вас вообще не будет изображения для браузеров, в которых отключены сценарии. Следовательно, нам нужен лучший способ работы с адаптивными изображениями. И, к счастью, он есть! Рекомендуемый способ - использовать:
srcset атрибут
sizes атрибут
picture элемент
Давайте углубимся немного глубже.
Атрибут srcset:
Прежде чем мы рассмотрим, как srcset на самом деле используется, давайте разберемся в нескольких терминах:
Соотношение устройство-пиксель
Соотношение устройство-пиксель - это количество пикселей устройства на пиксель CSS. На соотношение устройство-пиксель влияют два ключевых условия.:
- (количество физических пикселей на дюйм): плотность пикселей на устройстве Устройство с высоким разрешением будет иметь более высокую плотность пикселей и, следовательно, при том же уровне масштабирования будет иметь более высокое соотношение пикселей на устройстве по сравнению с устройством с более низким разрешением. Например: телефон Lumia 950 высокого класса будет иметь более высокое разрешение, чем бюджетный телефон Lumia 630, и, следовательно, при том же уровне масштабирования будет иметь более высокое соотношение пикселей на устройстве.
- Уровень масштабирования браузера: Для того же устройства более высокий уровень масштабирования означает большее количество пикселей устройства на пиксель CSS и, следовательно, более высокое соотношение устройство-пиксель. Для примера рассмотрим этот рисунок:
При увеличении масштаба в вашем браузере (Ctrl + плюс) количество пикселей CSS для вашего div остается прежним, но количество пикселей устройства, которые он занимает, увеличивается. Таким образом, у вас больше пикселей устройства на пиксель CSS.
Если вы хотите отображать отдельные изображения (или, как правило, отдельные ресурсы с одним и тем же изображением) в зависимости от соотношения пикселей на устройстве, вы можете использовать базовую реализацию srcset:
<img src="images/space-needle.jpg"
srcset="images/space-needle.jpg 1x, images/space-needle-2x.jpg 2x,
images/space-needle-hd.jpg 3x">
x дескриптор в атрибуте srcset используется для определения соотношения пикселей устройства. Следовательно,
- Для соотношения устройства и пикселей 1 будет использоваться изображение space-needle.jpg.
- При соотношении пикселей устройства и экрана 2 будет использоваться изображение space-needle-2x.jpg.
- Для соотношения сторон 3:1 будет использоваться изображение space-needle-hd.jpg.
src атрибут используется в качестве запасного варианта для браузеров, которые еще не поддерживают srcset реализацию. Это хорошо работает. Используя дескриптор x, вы всегда будете получать одно и то же изображение на устройствах с одинаковым соотношением устройство-пиксель, даже если это означает, что вы получаете одно и то же изображение на 13,5–дюймовом ноутбуке и 5-дюймовом мобильном телефоне, которые имеют одинаковое соотношение устройство-пиксель. Теперь предположим, что нам нужно изображение другого размера (высота, ширина) на большем или меньшем видовом экране. Здесь в игру вступают w descriptor in srcset и новый атрибут – sizes.
- Дескриптор w: описывает ширину ссылающегося изображения. Рассмотрим следующий пример:
<img src="images/space-needle.jpg"
srcset="images/space-needle.jpg 200w, images/space-needle-2x.jpg 400w,
images/space-needle-hd.jpg 600w">
- Здесь указано, что ширина первого изображения составляет 200 пикселей, второго — 400 пикселей, а третьего — 600 пикселей. Кроме того, если ширина экрана пользователя составляет 150 пикселей CSS, это соответствует следующему в терминах
x descriptors:
<img src="images/space-needle.jpg"
srcset="images/space-needle.jpg 1.33x, images/space-needle-2x.jpg 2.67x,
images/space-needle-hd.jpg 4x">
(Помните, что соотношение пикселей устройства и CSS — это просто количество пикселей устройства, делённое на количество пикселей CSS.)
Атрибут sizes:
Фактическая реализация, в которой вам нужно изображение разного размера (разной высоты, ширины) на разных размерах экрана, достигается с помощью sizes атрибут вместе с атрибутом w descriptor из srcset. Давайте снова рассмотрим пару примеров.:
Пример 1
Допустим, вы хотите, чтобы изображение отображалось на половине ширины области просмотра. Вы наберете:
<img src="images/space-needle.jpg" sizes="50vw"
srcset="images/space-needle.jpg 200w, images/space-needle-2x.jpg 400w,
images/space-needle-hd.jpg 600w">
Теперь браузер будет решать, какое изображение загружать, в зависимости от ширины браузера и соотношения пикселей устройства. Например:
Пример 2
Вы хотите, чтобы изображение отображалось на половине ширины области просмотра, когда ширина области просмотра больше 40em, но изображение должно занимать всю ширину, когда ширина области просмотра меньше или равна 40em. Вот как вы к этому подойдете:
<img src="images/space-needle.jpg" sizes="(max-width: 40em) 100vw, 50vw"
srcset="images/space-needle.jpg 200w, images/space-needle-2x.jpg 400w,
images/space-needle-hd.jpg 600w">
Это очень похоже на медиа-запросы. Итак, для 39em широкого окна просмотра, (max-width: 40em) значение true, что означает 100vw, что изображение такое же широкое, как и окно просмотра. Если областью просмотра является окно браузера и если ширина браузера составляет 500 CSS пикселей, изображение будет отображаться шириной 500 пикселей. Это эквивалентно указанию:
<img src="images/space-needle.jpg" sizes="(max-width: 40em) 100vw, 50vw"
srcset="images/space-needle.jpg 0.4x, images/space-needle-2x.jpg 0.8x,
images/space-needle-hd.jpg 1.2x">
Аналогично описанному выше, браузер сам решит, какое изображение выбрать сверху для конкретного отображения. Для 41em широкого окна просмотра (max-width: 40em) присваивается значение false, что означает 50vw, что изображение вдвое шире окна просмотра. Следующий элемент, который мы увидим, - это элемент picture, но перед этим мне нужно краткое описание :)
| Пример использования |
Решение |
| Я хочу, чтобы одно и то же изображение отображалось на всех устройствах, но я хочу отображать его в более высоком разрешении на устройствах, которые могут его поддерживать. Высота и ширина изображения должны оставаться фиксированными. |
Создайте несколько ресурсов из одного изображения (space-needle.jpg, space-needle-hd.jpg). Используйте srcset с дескриптором x. |
| Я хочу тот же сценарий, что и выше, но я должен иметь возможность настраивать высоту и ширину изображения в зависимости от области просмотра. |
Используйте sizes и srcset с дескриптором w (опять же, создайте несколько ресурсов из одного изображения) |
| Я сомневаюсь, что если я использую то же изображение для экрана меньшего размера, основной объект моего изображения может стать слишком маленьким. Я хочу отобразить другое изображение (более сфокусированное на основном объекте) с другим размером экрана, но я все еще хочу отображать отдельные ресурсы одного и того же изображения в зависимости от соотношения устройство-пиксель, и я хочу настроить высоту и ширину изображения в зависимости от области просмотра. |
? |
Решение ‘?’ - это picture элемент!
Элемент picture
Как мы видели выше, picture element используется, когда вы хотите отобразить другое изображение в зависимости от размера отображаемого изображения. Элемент picture представляет собой контейнер, который содержит другие элементы, управляющие загружаемым изображением. Давайте рассмотрим пример:
<picture>
<source media="(max-width: 20em)" srcset="images/small/space-needle.jpg 1x,
images/small/space-needle-2x.jpg 2x, images/small/space-needle-hd.jpg 3x">
<source media="(max-width: 40em)" srcset="images/medium/space-needle.jpg 1x,
images/medium/space-needle-2x.jpg 2x, images/medium/space-needle-hd.jpg 3x">
<img src="space-needle.jpg" alt="Space Needle">
</picture>
Выбирается первый source элемент, для которого media атрибут медиазапроса имеет значение true. Таким образом, если максимальная ширина области просмотра равна 20em, то соответствующий источник изображения выбирается из images/small каталога в зависимости от соотношения пикселей устройства. Все изображения в одном srcset обычно представляют собой несколько ресурсов с одним и тем же изображением. Сам picture элемент ничего не отображает. Даже source элемент внутри picture элемента не представляет ничего своего. source Элемент должен содержать srcset атрибут, и он может иметь sizes, media и type атрибуты. Необходимо добавить img элемент внутри picture. Вы не увидите ни одного изображения без img элемента. Все source элементы внутри picture элемента предназначены только для того, чтобы указать источник изображения. Вы также можете выбрать изображение на основе формата изображения, поддерживаемого браузером. Это особенно полезно, когда размер изображения значительно экономится только в зависимости от формата. Например, Microsoft Edge и IE9+ поддерживают эффективный формат изображений JPEG-XR, который обычно занимает меньше места, чем JPG. Используя атрибут type в элементе source, вы можете проверить наличие этого формата:
<picture>
<source media="(max-width: 30em)" type="image/vnd.ms-photo"
srcset="images/small/space-needle.jxr 1x, images/small/space-needle-2x.jxr 2x,
images/small/space-needle-hd.jxr 3x">
<source media="(max-width: 30em)" type="image/jpg"
srcset="images/small/space-needle.jpg 1x, images/small/space-needle-2x.jpg 2x,
images/small/space-needle-hd.jpg 3x">
<img src="space-needle.jpg" alt="Space Needle">
</picture>
При его использовании оба атрибута: media и type должны иметь значение true, чтобы этот source элемент был выбран. Если браузер не может распознать ни один из форматов, он возвращается к img.
Собираем все это вместе
Разобравшись с тем, как работают адаптивные изображения, давайте рассмотрим полный пример, в котором используются все три варианта — srcset, sizes и picture.
<!DOCTYPE html>
<html>
<head>
<title> Responsive images are here! </title>
</head>
<body style="width:100%">
<picture>
<source media="(max-width: 700px)" sizes="(max-width: 500px) 50vw, 10vw"
srcset="stick-figure-narrow.png 138w, stick-figure-hd-narrow.png 138w">
<source media="(max-width: 1400px)" sizes="(max-width: 1000px) 100vw, 50vw"
srcset="stick-figure.png 416w, stick-figure-hd.png 416w">
<img src="stick-original.png" alt="Human">
</picture>
</body>
</html>
В этом примере мы использовали picture элемент, который содержит несколько source элементов. Первый из них выбирается, если максимальная ширина составляет 700 пикселей. Если выбран этот вариант, то атрибут sizes определяет размер отображаемого изображения на основе упомянутых нами точек останова по ширине. Реализация точно такая же, как и в атрибуте sizes . Таким образом, если максимальная ширина составляет 500 пикселей (ширина варьируется от 0 до 500 пикселей), изображение будет занимать половину области просмотра. Источник изображения выбирается в зависимости от соотношения пикселей на устройстве. Однако если ширина области просмотра превышает 500 пикселей (но <=700px , поскольку мы находимся внутри первого source элемента), то изображение будет занимать всего 1/10 области просмотра. Аналогично, второй source элемент выбирается, если максимальная ширина равна 1400px (что означает, что теперь ширина колеблется от 701px до 1400px). Атрибут sizes гарантирует, что если ширина области просмотра варьируется от 701px до 1000px, ширина изображения будет такой же, как ширина области просмотра, а если ширина области просмотра варьируется от 1001px до 1400px, изображение займет половину ширины области просмотра. Чтобы проверить все случаи, я просто изменяю размер браузера и проверяю. В реальных условиях доступ к вашему веб-сайту будет осуществляться с разных устройств, и именно там вы увидите реальное использование адаптивных изображений. Вот результат: (Пожалуйста, обратите внимание, что все источники изображений и установленная ширина изображения приведены только для демонстрации!) Ширина области просмотра устанавливается в диапазоне от 1001px до 1400px: ширина изображения равна половине ширины области просмотра
Ширина области просмотра устанавливается в диапазоне от 701px до 1000px: ширина изображения такая же, как ширина области просмотра.
Ширина области просмотра устанавливается в диапазоне от 501 до 700 пикселей: ширина изображения составляет 1/10 ширины области просмотра.
Ширина области просмотра устанавливается в диапазоне от 0 до 500 пикселей: ширина изображения равна половине ширины области просмотра. 
И мы почти закончили!
Адаптивные изображения дают вам, разработчику, возможность обеспечить наилучшее взаимодействие с вашими пользователями на нескольких устройствах, которые они используют для просмотра вашего веб-сайта. Сейчас самое время начать интегрировать его в свой веб-сайт, если вы еще этого не сделали. Надеюсь, вам было интересно читать это!
Часто задаваемые вопросы о создании адаптивных изображений с помощью Srcset
Какова цель использования srcset в HTML?
Атрибут srcset в HTML используется для указания различных изображений, которые будут загружаться на разные устройства, в зависимости от размера дисплея или разрешения устройства. Это особенно полезно в адаптивном веб-дизайне, где целью является обеспечение оптимального удобства просмотра на широком спектре устройств. Используя srcset, вы можете гарантировать, что устройства меньшего размера будут загружать изображения меньшего размера, экономя пропускную способность и увеличивая время загрузки страницы.
Как браузер выбирает, какое изображение отображать при использовании srcset?
При использовании srcset браузер выбирает наиболее подходящее изображение в зависимости от текущего размера области просмотра, плотности пикселей устройства и размеров изображений, указанных в атрибуте srcset. Браузер всегда будет стараться выбрать наилучшее изображение, которое обеспечит удобство просмотра без лишних затрат трафика.
Могу ли я использовать srcset с элементом picture?
Да, вы можете использовать атрибут srcset с элементом изображения. Это позволяет указать несколько источников для изображения, каждый из которых соответствует разным условиям отображения. Браузер выберет первый источник, который соответствует текущему окну просмотра и характеристикам устройства.
В чем разница между атрибутами srcset и sizes?
Атрибут srcset используется для указания разных изображений для разных разрешений устройств, а атрибут sizes используется для указания размера изображения в пикселях CSS. Атрибут sizes сообщает браузеру, сколько места займёт изображение в макете, что помогает браузеру выбрать наиболее подходящее изображение из списка srcset.
Как я могу указать изображение по умолчанию для браузеров, которые не поддерживают srcset?
Вы можете указать изображение по умолчанию для браузеров, которые не поддерживают srcset, используя атрибут src вместе с атрибутом srcset. Атрибут src указывает резервное изображение, которое будет использоваться в случае, если браузер не поддерживает srcset или если ни одно из изображений, указанных в srcset, не соответствует характеристикам текущего устройства.
Могу ли я использовать srcset для загрузки различных форматов изображений?
Да, вы можете использовать srcset для загрузки изображений в разных форматах. Это может быть полезно, если вы хотите использовать преимущества новых форматов изображений, таких как WebP, которые обеспечивают лучшее сжатие, чем традиционные форматы, такие как JPEG, но поддерживаются не всеми браузерами.
Что такое дескриптор x в srcset?
Дескриптор x в srcset используется для указания плотности пикселей в изображениях. Это позволяет создавать изображения с высоким разрешением для устройств с дисплеями с высокой плотностью пикселей, например для дисплеев Retina.
Как srcset работает с медиазапросами CSS?
Атрибут srcset работает независимо от медиазапросов CSS. В то время как медиазапросы используются для применения различных стилей CSS в зависимости от характеристик устройства, атрибут srcset используется для загрузки различных изображений в зависимости от характеристик устройства. Однако вы можете использовать их вместе для создания полностью адаптивного дизайна.
Могу ли я использовать srcset с фоновыми изображениями?
Нет, атрибут srcset можно использовать только с элементами img и source. Для фоновых изображений можно использовать медиазапросы CSS для загрузки разных изображений в зависимости от характеристик устройства.
Поддерживается ли srcset всеми браузерами?
Атрибут srcset широко поддерживается всеми современными браузерами, включая Chrome, Firefox, Safari и Edge. Однако он не поддерживается Internet Explorer. Для максимальной совместимости следует предоставить резервное изображение с помощью атрибута src.