Как создавать адаптивные изображения. Атрибут srcset
Адаптивные изображения автоматически изменяют свой размер, чтобы соответствовать экрану пользователя, что улучшает вид страницы и ускоряет загрузку.
Давайте рассмотрим несколько способов создания адаптивных изображений.
В статье мы говорим о пикселях и ретина-дисплеях. Если вы не знаете, что это такое — прочитайте статью.
Метод описания плотности экрана
Метод подходит для тех изображений, размер которых фиксирован на экранах повышенной плотности. Это значит, что для некоторых изображений шириной 200px , указанной в HTML, можно загрузить картинку шириной 600px или больше, так как на экране повышенной плотности она будет смотреться намного лучше.
Как сделать изображение адаптивным с помощью srcset
- Реагировать на ретину — загружать разные картинки для разной плотности пикселей;
- Реагировать на ширину вьюпорта — загружать разные картинки для разных медиавыражений;
- Работать с новыми форматами изображений (AVIF и WebP).
Чтобы реализовать метод, используем атрибут srcset для описания плотности экрана. Атрибут srcset позволяет указать несколько вариантов изображений с разными разрешениями или плотностями пикселей. Браузер выбирает наиболее подходящее изображение на основе плотности пикселей экрана устройства, чтобы загрузить его.

1x , 2x , 3x — это идентификатор, который указывает плотность экрана для показа определённой картинки. Разработчик выбирает какие идентификаторы нужно указать для разных устройств.
Дескрипторы ширины, высоты и плотности
В атрибуте srcset можно использовать различные виды дескрипторов для указания вариантов изображений в зависимости от конкретных требований.
Дескриптор ширины (w — width descriptor) указывает ширину изображения или вьюпорта, для которого предназначено конкретное изображение. Измеряется в пикселях.
В этом примере medium.jpg имеет дескриптор 1000w , значит изображение предназначено для вьюпортов шириной 1000px, соответственно, large.jpg — изображение для вьюпортов шириной 2000px.
Дескриптор размера (x — pixel density descriptor) указывает отношение между шириной изображения и шириной вьюпорта. Он измеряется в вещественных числах без единицы измерения.
Здесь у medium.jpg дескриптор 1.5x , значит, ширина изображения в полтора раза больше ширины вьюпорта. У large.jpg ширина изображения в два раза больше ширины вьюпорта.
Дескриптор плотности пикселей (dppx — dots per pixel descriptor) задаёт плотность пикселей изображения или экрана, для которого предназначена конкретная картинка. Он измеряется в пикселях на дюйм ( ppi ).
Дескриптор 1.5dppx означает, что изображение предназначено для устройств с плотностью 1.5 пикселя на дюйм. Изображение large.jpg подойдёт для устройств с плотностью 2 пикселя на дюйм, например, для планшетов, ноутбуков или мониторов с очень высоким разрешением.
Использование атрибута srcset позволяет создавать адаптивные изображения, которые оптимально подстраиваются под различные устройства и экраны. Когда браузер загружает страницу, он анализирует дескрипторы изображений и выбирает наиболее подходящее на основе характеристик экрана и возможностей браузера.
Кадрирование изображений и тег
Если по дизайну сайта изображение на разных устройствах немного меняется, например, кадрируется или приобретает дополнительные детали, его удобно верстать с помощью тега .

Как добавить адаптивное изображение с помощью
Указываем открывающий и закрывающий тег . Внутри этого контейнера будем определять разные источники изображений.
Атрибут media описывает условия, при которых будет загружаться соответствующее изображение. Например, media=»(min-width: 1200px)» означает, что изображение logotype-desktop.svg будет загружаться, если ширина экрана равна или больше 1200px .
- В зависимости от условий задать нужное изображение;
- Рассказать браузеру о наличии картинок в новых форматах и указать, какая из них подходит к вьюпорту;
- Кадрировать картинку.
В конце добавляем элемент , который будет использоваться в случае, если браузер не поддерживает тег или не выполняется ни одно из условий, определённых в тегах . Здесь указываем путь к изображению img/logotype-phone.svg и добавляем альтернативный текст с помощью атрибута alt .
Материалы по теме
- Как изменить ширину элемента. Свойство width
- Как создавать адаптивные сетки
- Как добавить изображение на страницу
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Как сделать картинку адаптивной

Всем привет. Задержался я с новой статьей (устроил себе несколько дней выходных и уехал на море). Но надеюсь, что этой статьей немного заглажу этот инцидент 🙂
Проблема адаптивных картинок довольно актуальна, поэтому начну с небольших рассуждений и способов реализации, а потом выделю вариант, который, как по мне подходит наилучшим образом.
Итак, около года назад я считал, что для того, чтобы сделать картинку адаптивной (то есть сделать так, чтобы она растягивалась или сжималась по ширине контейнера), достаточно воспользоваться следующим кодом:
.wrapper img
И действительно, в некоторых случая этим можно ограничиться. Этот трюк отлично работает, когда окно браузера становится меньше. Но что, если ширина контейнера, в котором лежит картинка, становится больше разрешения картинки? Правильно. Картинка растягивается по ширине контейнера, но качество оставляет желать лучшего. А что делать, если нужна поддержка разрешения 2048x1536px?
Если вы не используете svg и это растровое изображение, то первое, что приходит на ум, — это взять картинку, которая подходила бы к максимальному разрешению landing page, а уже с изменением размера окна браузера, она будет сжиматься с нормальным качеством.
И тогда возникает проблема производительности. Глупо для смартфона подгружать такие большие картинки, которые хорошо смотрятся на retina разрешении. Ведь скорость мобильных сетей не такая высокая, как у ПК, и некоторые пользователи могут не дождаться загрузки лендинга на своем смартфоне. А в результате — это потерянный клиент.
Можно попробовать задать несколько дивов с картинками, а потом, при помощи медиазапросов, скрывать ненужные и показывать только ту картинку, которая подходит под текущее разрешение.
Вроде бы проблема решена. Но дело в том, что браузеры, для того, чтобы ускорить отображение страницы предзагружают картинки, которые прописаны в html до того, как начнет обрабатываться css. Может я не совсем правильно выразился (поправьте), но если провернуть такой трюк, то все картинки все равно будут загружены, вне зависимости от того, что прописано в css. А значит мы только усугубили положение для мобильных устройств. Теперь им придется грузить не одно, а несколько изображений.
В этом можно убедиться, открыв инструменты разработчика и заглянув во вкладку «Сеть».

Вообще, существует еще много проблем, которые могут возникнуть при верстке адаптивных изображений. И решений, накопилось тоже не мало. Все зависит от конкретной ситуации.
В html 5 появился тег picture, который позволяет решить большинство проблем и создан именно для создания адаптивного (отзывчивого) дизайна. Его конструкция напоминает теги video и audio. Суть работы заключается в том, что внутри тега picture задаются несколько изображений под конкретные разрешения экрана. Выглядит это примерно так:
Особенность в том, что вместо src — используется srcset и применяется что-то похожее на медиазапросы. Маленькая картинка грузится при разрешении меньше 319px. Среднее изображение при разрешении от 320px до 480px и т.д.
Вообще, при использовании новых тегов, я рекомендую заглядывать на это сайт и проверять текущее положение вещей.
Как видите ситуация на данный момент оставляет желать лучшего. Нет поддержки на IOS устройствах, на Macbook(ах) и на IE (Хотя, пользователей IE — не жалко, они должны страдать 🙂 ). Думаю, что все мы не готовы терять такое количество пользователей. Нет, неправильно выразился. Не терять, ведь наша основная картинка загрузится и корректно отобразится. Но все равно, хотелось бы не терять клиентов с техникой apple из-за долгой загрузки страницы, так как это, скорее всего, платежеспособная аудитория 🙂
Теперь все устройства должны поддерживать такую структуру верстки адаптивных картинок. Правда на Маке я не тестировал (не обзавелся пока).

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

Логика быстрого отображения изображения довольно сложна. Она включает в себя определение размера изображения, а также понимание того, использует ли пользователь дисплей с высоким разрешением. К счастью, браузер оснащен лучше, чем мы, чтобы справиться с этой логикой. Все, что нам нужно сделать, это предоставить ему несколько подсказок. Мы будем использовать атрибут srcset, чтобы предоставить список ресурсов изображения на выбор, и атрибут sizes, чтобы сообщить браузеру, насколько большое изображение будет отображаться в различных контрольных точках.
О, и не беспокойтесь о поддержке браузерами! Мало того, что эти атрибуты имеют отличную поддержку по всем направлениям, мы также будем предоставлять запасной вариант для старых браузеров, таких как IE11.
Атрибут srcset
Атрибут srcset предоставляет браузеру множество источников на выбор, а также размер каждого из этих источников.

Это разделенный запятыми список URL-адресов с шириной для каждого. Каждый элемент в списке выглядит так: «image.jpg 1000w,», что сообщает браузеру, что файл image.jpg имеет ширину 1000 пикселей.
Предоставляя таким образом набор графических ресурсов, вы говорите браузеру: «Я даю тебе список изображений и надеюсь, что ты выберешь лучший».
Браузер выберет наилучшее изображение на основе сложного набора критериев, в том числе того, какой размер изображения отображается пользователю при его текущем размере окна просмотра, и работает ли пользователь на дисплее с высоким разрешением.
Он достаточно умен, чтобы знать, что на экране настольного компьютера с низким разрешением, если изображение будет отображаться с шириной 800 пикселей, ему следует выбрать ресурс из списка шириной не менее 800 пикселей.
Также ему будет известно, что если изображение будет отображаться с шириной 320 пикселей на retina-экране, ему следует выбрать ресурс шириной не менее 640 пикселей. Так что вам не придется беспокоиться о 1x и 2x ресурсах. Все, что вам нужно сделать, это предоставить хороший набор изображений, а браузер сделает все остальное.
Не уверены, какой размер изображения предоставить? Читайте дальше!
Атрибут sizes
Атрибут srcset работает отлично, но когда браузер читает HTML, он не знает, использовали ли вы CSS , чтобы масштабировать изображение, например, на 50% от ширины экрана.
Вот когда в игру вступает атрибут sizes. С его помощью мы даем браузеру подсказку о том, как будет отображаться изображение после применения CSS.

Атрибут sizes представляет собой список разделенных запятыми медиа условий с шириной для каждого. Каждый элемент в списке выглядит следующим образом: «(min-width: 1023px) 780px,», это говорит браузеру, что, когда область просмотра имеет ширину 1023 пикселя (или шире), изображение будет иметь ширину ровно 780 пикселей.
Вы также можете использовать относительную ширину, например, 50vw, при которой изображение будет составлять 50 процентов от ширины области просмотра. Вы даже можете использовать calc для более сложных ситуаций. Например, calc(50vw — 2rem) говорит, что изображение будет составлять 50 процентов от ширины области просмотра, минус 2rem, возможно, чтобы учесть некоторые отступы или границы.
Для последнего элемента в списке не должно указываться условие. Если вы указали ширину и не указали условие, оно будет считаться шириной по умолчанию, которая будет использоваться, если другие условия не удовлетворяются.
Браузер будет проходить вниз по этому списку и применять первый элемент, который соответствует области просмотра. Так, если задан атрибут sizes:
( min — width : 1023px ) 780px ,
( min — width : 675px ) 620px ,
Если пользователь работает на большом настольном дисплее, браузер сопоставляет первый элемент в списке и знает, что изображение будет иметь ширину 780 пикселей.
Стандартный iPad в вертикальной ориентации имеет ширину 768 пикселей, поэтому браузер пропускает первый элемент, но выбирает второй, что говорит о том, что изображение будет иметь ширину 620 пикселей.
Пользователь на обычном мобильном устройстве не будет соответствовать ни одному из первых двух условий, что говорит о том, что изображение будет иметь 100% ширины области просмотра.
Конечно, это всего лишь примеры, в реальном мире все сложнее. Пользователь с большим дисплеем, но при узком окне просмотра получит уменьшенное изображение. Пользователь на iPad Pro может получить большое изображение при удерживании планшета в альбомной ориентации, среднее изображение при удерживании в портретном режиме или маленькое изображение при использовании браузера в режиме разделенного экрана. Некоторые смартфоны могут соответствовать второму правилу при альбомной ориентации. В этом прелесть системы — вам не нужно думать обо всех этих форм-факторах. Вам нужно только учитывать, какой размер изображения отображать на основе ширины области просмотра.
Не уверены, какие значения объявлять? Читайте дальше!
Атрибут src
Возможно, вы заметили, что все приведенные мною примеры все равно содержат атрибут src, и задаетесь вопросом, нужен ли он по-прежнему. Ответ таков: если вы укажете атрибут srcset, современные браузеры заменят значение src в DOM изображением, выбранным из srcset. Поэтому современные браузеры игнорируют значение, указанное в атрибуте src в пользу srcset.
Но src все еще важен для браузеров, которые не поддерживают адаптивные изображения. Эти старые браузеры будут игнорировать атрибуты srcset и sizes, потому что они не могут их понять. Однако они понимают атрибут src, поэтому вы можете предоставить для них одно изображение в качестве запасного варианта. Я обычно выбираю самое маленькое изображение, которое все равно будет хорошо смотреться на настольном не-retina мониторе.
Вопросы и ответы
Как я должен генерировать ресурсы изображения?
Вы можете создавать изображения несколькими способами: вручную, с помощью адаптивного генератора изображений или с помощью CDN с изображениями.
Чтобы создать изображения вручную, откройте исходное изображение в Photoshop (или в любом другом редакторе) и экспортируйте его во все нужные размеры.
Это может занять немного времени, поэтому вы можете использовать инструмент для генерации изображений. Несколько инструментов позволяют это сделать, но мне больше всего нравится Responsive Image Breakpoints Generator от Cloudinary. Вы загружаете изображение, и он автоматически генерирует различные размеры. Вы можете настроить параметры, чтобы контролировать, сколько изображений он генерирует. Затем вы можете скачать изображения для использования.
Другой вариант — разместить изображения в CDN, например, в Cloudinary или imgix. При использовании подобного сервиса вы загружаете в CDN изображение с самым высоким разрешением, а затем можете запросить версии изображения с измененным размером, используя параметры URL. Вам не нужно выполнять какую-либо работу, вы просто сообщаете CDN, в каком размере хотите отображать изображение.
Какие размеры изображения я должен предоставить?
Это важный вопрос! Если вы предоставляете слишком много ресурсов, вы тратите свое время и энергию на их создание. Если вы предоставляете слишком мало, вы заставляете своих пользователей загружать изображения большего размера, чем им нужно.
Если вы имеете дело с одним изображением и можете предоставить пользовательскую разметку для этого изображения, вы можете использовать Responsive Image Breakpoints Generator от Cloudinary. Он автоматически проверит изображение и определит, какой оптимальный набор ресурсов необходим для обеспечения наилучшего баланса между размером файла и разрешением. После этого он не только генерирует файлы, но он также указывает атрибуты srcset и sizes.

Если вы работаете в CMS или веб-приложении, когда вы не знаете, какое точно изображение будет отображаться в слоте, я рекомендую выбрать стандартный массив размеров изображения. В прошлом, я использовал 320w, 640w, 960w, 1280w, 1920w, и 2560w, потому что это круглые числа, которые следуют в логической последовательности (кратные 320). Этот набор охватывает размеры от мобильного до настольного.
Однако стандартный массив размеров всегда будет менее эффективным, чем настроенный. В этом случае, хотя числа логичны, размер файла постепенно увеличивается, потому что когда вы удваиваете ширину, вы в четыре раза увеличиваете количество пикселей. В результате, если вам нужно выбрать массив стандартного размера, вы можете рассмотреть тот, у которого меньше ресурсов при небольших размерах и больше при больших размерах.
Если вы размещаете изображения в Cloudinary, вы можете воспользоваться другим подходом, который заключается в использовании API Cloudinary для запуска Генератора адаптивных точек при их загрузке! Тогда вы можете принять ответ от API для динамического заполнения атрибутов srcset и sizes.
Какие значения sizes я должен объявить?
Вам нужно определить, какие размеры добавить в атрибут sizes, посмотрев на CSS, чтобы определить, насколько широко изображение отображается в различных контрольных точках. Иногда это определяется шириной самого изображения:
Адаптивные изображения. Что использовать: img или picture?
Теги img и picture предназначены для загрузки изображений. Каждый из них позволяет задать набор правил, согласно которым браузер будет выбирать, какое из изображений загружать. Рассмотрим синтаксис и различия данных тегов. Для начала нужно задать следующий метатег:
Данный метатег указывает браузеру выполнять масштабирование размеров экрана устройства. Так, например, размеры экрана iPhone X составляют 375×812 css-пикселей.
Для тестирования будем использовать следующее изображение:

Тег img
Атрибут srcset предназначен для указания всех доступных размеров изображений и URL каждого из них. При этом, тег src указывать нужно. Его значение будет использовано, если все варианты из srcset не подойдут согласно указанным правилам.
Атрибут srcset содержит список из одной или нескольких строк, разделённых запятыми, указывающих набор источников изображения. Каждая строка состоит из:
- URL изображения.
- Дескриптора ширины.
Рассмотрим на примере:

Ширина всех доступных изображений указывается в пикселях. По историческим причинам для обозначения пикселей используется символ w . В данном примере атрибут srcset содержит три изображения, ширина которых 480, 960 и 1920 пикселей соответственно. Браузер выберет изображение в зависимости от ширины экрана устройтва и его плотности пикселей. Если ширина экрана не превышает 480 css-пикселей, то будет выбрано следующее изображение:
- bears-480×270.jpg , если коэфициент плотности пикселей равен 1.
- bears-960×540.jpg , если коэфициент плотности пикселей равен 2 (retina display).
- bears-1920×1080.jpg , если коэфициент плотности пикселей больше 2.
Аналогично, если ширина экрана больше 480 css-пикселей, но не превышает 960 css-пикселей, то:
- bears-960×540.jpg , если коэфициент плотности пикселей равен 1.
- bears-1920×1080.jpg , если коэфициент плотности пикселей больше или равен 2.
При этом браузер будет подразумевать, что изображение занимает всю ширину экрана. Для переопределения такого поведения предназначен атрибут sizes , который содержит список из одной или нескольких строк, разделённых запятыми, указывающих какую максимальную ширину может занимать изображение при определённом размере экрана. Каждая строка состоит из:
- Медиа выражения.
- Ширины изображения.
Рассмотрим на примере:

В данном примере браузер будет следовать следующим правилам при выборе источника изображения:
- Если ширина экрана устройства составляет не более 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.
- Если ширина экрана устройства составляет от 600 до 1200 css-пикселей, то изображение на таком экране занимает максимум 960 css-пикселей в ширину.
- В противном случае браузер будет подразумевать, что изображение может занимает всю ширину экрана.
Также нужно учитывать коэфициент плотности пикселей. Например, если ширина экрана устройства составляет 550 css-пикселей, то браузер выберет следующее изображение:
- bears-480×270.jpg , если коэфициент плотности пикселей равен 1. Так как ширина экрана устройства не превышает 600 css-пикселей, то изображение на таком экране занимает максимум 480 css-пикселей в ширину.
- bears-960×540.jpg , если коэфициент плотности пикселей равен 2.
- bears-1920×1080.jpg , если коэфициент плотности пикселей больше 2.
Атрибут sizes нужно указывать, если размеры изображения ограничены css стилями. Если атрибут sizes не указан, то по умолчанию он будет иметь значение 100vw (sizes=»100vw» ), то есть браузер будет подразумевать, что изображение может занимает всю ширину экрана.
Тег picture
Тег picture служит контейнером для одного или более тегов source и одного тега img . Тег source представляет собой источник изображения. Он содержит информацию о формате изображения и его размерах, а также правила, при соблюдении которых браузер должен выбрать этот источник. Если все источники не подходят, то будет выбран файл, указанный в атрибуте src тега img . Если сразу несколько источников подходят, то браузер выберет первый по порядку.
Тег source имеет атрибуты sizes и srcset . Они работают также, как и соотвествующие атрибуты у тега img . Рассмотрим на примере:

Данный пример работает так же, как и второй пример использования тега img .
Разница между img и picture
Тег picture позволяет указать браузеру использовать разные изображения в зависимости от размера экрана. Достигается это за счёт использования атрибута media тега source , который позволяет задать медиа выражение, при котором будет использоваться данный источник. Например, на маленьких экранах мы хотим использовать обрезанное изображение cropped-bears.jpg , которое содержит основную часть изображения:

Для этого нужно указать несколько тегов source и задать им атрибуты media :

В данном примере, если ширина экрана устройства не превышает 480 css-пикселей, то будет выбрано обрезанное изображение. Добиться такого результата при помощи тега img не получиться, так как изображения cropped-bears-960×540.jpg и bears-960×540.jpg имеют одинаковый размер, но изображение cropped-bears-960×540.jpg предназначено для использования на устройстве, ширина которого не превышает 480 css-пикселей и коэфициент плотности пикселей равен 2, а изображение bears-960×540.jpg — на устройстве, ширина которого от 480 до 960 css-пикселей и коэфициент плотности пикселей равен 1.
Также, тег picture позволяет указать различные форматы изображения, например webp и jpeg . Для этого нужно тегу source задать атрибут type:

Источники с наименее поддерживаемыми типами нужно располагать в начале списка, так как браузер выберет первый по порядку подходящий источник. В данном примере браузер выберет тип изображения webp , если он его поддерживает. В противном случае будет выбран тип jpeg .
