Как адаптировать картинку под разрешение экрана html

Обновлено: 07.07.2024

Изображения заведомо являются одним из самых сложных аспектов адаптивного веб дизайна. Сегодня мы рассмотрим как элемент <picture> , являющийся решением проблемы адаптивных изображений, можно использовать прямо сейчас.

Вначале о проблеме

Времена попиксельного (pixel perfect) и дизайна фиксированной ширины (fixed-width) ушли в прошлое. Теперь во времена широкоформатных мониторов, интернет телевидения, планшетов и смартфонов различных размеров наши дизайны должны удовлетворять любому устройству шириной от 320px до потенциальных 7680px.

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

Так что же нам делать?

Текущее общепринятое решение

Как правило, вы найдете этот код на любом сайте с адаптивные дизайном:

Здесь используется max-width: 100%; для гарантии того, что изображение никогда не выйдет за пределы ширины родительского контейнера. Если родительский контейнер сжимается до ширины, меньшей чем ширина изображения - последнее сжимается вместе с контейнером. Установка height: auto; нужна для сохранения пропорций.

Одно "жидкое" изображение под все случаи

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

Новое решение: <picture>

<picture> это новый элемент, который является частью HTML5.

Он реализует способ описания адаптивных изображений таким же способом, как это делается в <audio> и <video> . Таким образом можно размещать несколько тегов <source> , каждый из которых содержит имена файлов различных изображений вместе с условиями, при которых те должны быть загружены.

Это позволит загружать разные изображения в зависимости от:

  • Результатов media выражений, например высоты, ширины или ориентации видимой области
  • Плотности пикселей

Это в свою очередь означает, что вы можете:

  • Загружать файлы изображений соответствующего размера, эффективно используя пропускную способность.
  • Загружать по-разному ориентированные изображения в разных пропорциях для того, чтобы соответствовать изменениям в макете при разных ширинах.
  • Загружать изображения с высоким разрешением для дисплеев с повышенной плотностью пикселей.

Как работает <picture> ?

Основные шаги при работе с <picture> :

  1. Создайте открывающий и закрывающий теги <picture></picture> .
  2. Внутри создайте <source> элемент для каждого выражения, что хотите обработать.
  3. Добавьте атрибут media , содержащий выражения для таких вещей как высота и ширина области просмотра, ориентация и т.д.
  4. Добавьте атрибут srcset с соответствующим именем файла изображения для загрузки.
  5. Добавьте дополнительные имена файлов к атрибуту srcset , если нужно поддерживать разную плотность пикселей, например для Retina дисплеев.
  6. Добавьте резервный (fallback) элемент <img> .

Вот простой пример, где для случая, когда ширина видимой области меньше 768px - загружается уменьшенное (smaller) изображение:

Можно заметить, что синтаксис, используемый в атрибуте media является таким же, как и при использовании в CSS media queries. Вы можете использовать те же самые проверки, т.е. проверять max-width , min-width , max-height , min-height , orientation и т.д.

Эти проверки можно использовать для того, чтобы например загружать альбомную (landscape) или книжную (portrait) версию изображения в зависимости от ориентации устройства, к тому же можно одновременно проверять размеры в этих выражениях. Например:

Этот код загружает уменьшенную альбомную (landscape) версию изображения для устройств с малым экраном и соответствующей ориентацией. И увеличенную версию того же изображения для устройств с большим экраном.

Если устройство имеет книжную (portrait) ориентацию - загружается книжная версия изображения, уменьшенная для устройств с малым и увеличенная для устройств с большим экраном.

Если вы хотите предоставлять изображения в другом разрешении для дисплеев с повышенной плотностью пикселей, это можно сделать, указав дополнительные имена файлов в атрибуте srcset . Давайте к примеру посмотрим на наш первый кусок кода с добавлением обработки для Retina 2x дисплеев:

Т.к. сначала обрабатывается media query, вы можете управлять размерами изображения, с которыми оно будет показано на экране. Затем будет проверяться плотность пикселей: если дисплей поддерживает повышенную плотность и в пользовательских настройках есть на это разрешение - будут загружены соответствующие версии изображений.

Использование <picture> сегодня

Прямо сейчас встроенная поддержка <picture> реализована в Chrome, Firefox и Opera. В будущем, вполне вероятно, мы увидим широкую поддержку и другими браузерами. Но до этого момента еще надо дожить.

Тем временем вам не нужно ждать, если хотите использовать <picture> прямо сейчас. Просто воспользуйтесь Picturefill 2.0; polyfill от умных людей из Filament Group.




После скачивания файла picturefill.js в свой проект просто подключите его в шапке:

Есть также опция для асинхронной загрузки скрипта, о которой можно прочитать в документации Picturefill.

При использовании этого скрипта элемент <picture> будет работать так, как я и объяснял, но с несколькими ограничениями.

Ограничения Picturefill

Picturefill отлично работает с разными версиями IE, однако IE9 не поддерживает <source> элементы, которые используются внутри <picture></picture> . Чтобы обойти это, оберните source элементы в <video> теги с помощью условных комментариев; это сделает их видимыми для IE9, например:

Android 2.3

Как и IE9, Android 2.3 не показывает <source> элементы внутри <picture> . Однако он понимает атрибут srcset при использовании в обычных <img> тегах. Убедитесь в том, что всегда включаете резервный <img> с именем файла по умолчанию в атрибут srcset для Android 2.3 и других браузеров, которые могут иметь такую же проблему.

Требуется JavaScript и встроенная поддержка Media Query

Соответственно требуется, чтобы JavaScript был включен в браузере. Picturefill 2.0 не предоставляет «no-js» решения, ведь если это будет сделано, то когда браузер выкатит нативную поддержку <picture> - будет показываться уже несколько изображений. Однако, вы можете использовать Picturefill 1.2, если параметр «no-js» является для вас обязательным.

Другим требованием Picturefill является встроенная поддержка media query, чтобы позволить обрабатывать выражения в атрибуте media . Все современные браузеры поддерживают media-выражения, лишь IE8 и ниже не имеют их поддержки, что соответствует лишь малой части пользователей.

Возможно, что в браузерах, которые имеют встроенную поддержку srcset , но пока не имеют поддержки <picture> , указанный в резервном элементе <img> файл может быть запрошен до того, как будет определен подходящий вариант из <source> .

Это лишь временная проблема, и она пропадет как только выкатят встроенную поддержку <picture> .

У веб-разработчика два врага: дедлайны и изображения. Хватит пытаться втиснуть картинку в макет! Вот 5 методов для полного контроля над графикой.

адаптивные изображения

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

Быстрое решение

Легким движением руки изображение превращается. в элегантный фон!

Все мы хоть раз пользовались этим читерским приемом, правда?

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

Решение из будущего

У тега <img> тоже существует одно чудесное свойство – object-fit . Кстати, оно работает и для видео-контейнеров.

Вот и все! object-fit управляет размещением элемента, если ширина и высота отличаются от его настоящего размера. Вместо cover можно использовать значение contain .

В чем подвох?

К сожалению, свойство не работает в IE и старых версиях Safari, но для них есть полифилл.


Решение Netflix

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

Эта техника может показаться сложной, но она стоит того, чтобы потратить время и разобраться. Ее используют многие сайты, включая Netflix!


Простое решение

Вероятно, вы его уже знаете и не раз использовали:

Если у вас не очень сложная разметка, эту технику можно использовать везде.

Продвинутое решение

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

В современных браузерах адрес изображения может изменяться в зависимости от ширины окна. Для этого существует атрибут srcset !

Его можно комбинировать с тегом HTML5 <picture> , который обеспечивает изящную деградацию до простого <img> .

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

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

Также вы узнаете некоторые общие проблемы, которые могут возникнуть при попытке сделать изображения адаптивными. Я постараюсь объяснить, как их решить.

Что мне следует использовать: относительные или абсолютные единицы?

Сделать изображение гибким или отзывчивым на самом деле довольно просто. Когда вы загружаете изображение на веб-сайт, оно имеет ширину и высоту по умолчанию. Вы можете изменить их с помощью CSS.

Чтобы изображение было отзывчивым, нужно присвоить новое значение его свойству width. Тогда высота изображения автоматически изменится.

Важно знать, что вы всегда должны использовать относительные единицы для свойства ширины, такие как процент, а не абсолютные единицы, такие как пиксели.

Например, если вы определите фиксированную ширину 500 пикселей, ваше изображение не будет отзывчивым, потому что единица измерения абсолютная.

Вот почему вам следует вместо этого назначить относительную единицу, например 50%. Такой подход сделает ваши изображения плавными, и они смогут изменять свой размер независимо от размера экрана.

Один из вопросов, который мне задают чаще всего, — следует ли использовать медиа-запросы.

Медиа-запрос — еще одна важная функция CSS, которая помогает сделать веб-сайт адаптивным. Я не буду вдаваться в подробности, но вы можете прочитать другой мой пост позже, чтобы узнать, как использовать медиа-запросы более подробно.

Ответ на этот вопрос: «это зависит от обстоятельств». Если хотите, чтобы изображение имело разные размеры от одного устройства к другому, нужно будет использовать медиа-запросы. В противном случае вы этого не сделаете.

Теперь для этого примера ваше изображение имеет ширину 50% для любого экрана. Но если вы хотите сделать его полноразмерным для мобильных устройств, понадобится помощь медиа-запросов:

Таким образом, в соответствии с правилом медиа-запроса любое устройство размером менее 480 пикселей будет занимать всю ширину экрана.

Другой способ, которым разработчики могут создавать адаптивные изображения, — это свойство max-width. Однако это не всегда лучший метод, поскольку он может работать не для всех размеров экрана и устройств.

Прежде чем перейти к примеру, необходимо понять, что именно делает свойство max-width.

Свойство max-width устанавливает максимальную ширину для элемента, которая не позволяет ширине этого элемента быть больше, чем его значение max-width (но может быть меньше).

Например, если изображение имеет ширину по умолчанию 500 пикселей, а размер вашего экрана всего 360 пикселей, вы не сможете увидеть полное изображение, потому что недостаточно места:

Поэтому вы можете определить свойство max-width для изображения и установить его на 100%, что сжимает изображение с 500 до 360 пикселей. Таким образом, вы сможете увидеть полное изображение на экране меньшего размера.

Хорошо то, что, поскольку вы используете относительные единицы, изображение будет плавным на любом устройстве размером менее 500 пикселей.

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

Другая распространенная проблема, с которой вы можете столкнуться, связана со свойством высоты. Обычно высота изображения автоматически изменяется, поэтому вам не нужно назначать свойство высоты вашим изображениям (потому что это как бы ломает изображение).

Но в некоторых случаях вам, возможно, придется работать с изображениями, которые должны иметь фиксированную высоту. Поэтому, когда вы назначаете фиксированную высоту изображения, оно все равно будет отзывчивым, но не будет хорошо выглядеть.

Есть две формы адаптивных изображений, и они предназначены для двух разных вещей.


Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Использование адаптивных изображений дает значительный прирост производительности. Вес изображения оказывает огромное влияние на общую производительность страниц, и адаптивные изображения являются одним из лучших способов снижения веса изображения. Представьте, что браузер может выбирать между изображением 300 × 300 или 600 × 600. Если браузеру требуется только 300 × 300, это потенциально экономия в 4 раза! Экономия обычно возрастает по мере уменьшения разрешения экрана и размера области просмотра; на маленьких экранах, как показывает пара из этих кейсов, возможна экономия в 70-90%.

Элемент picture также используется для резервных типов изображений и любого другого типа переключения медиа-запросов (например, для разных изображений в темном режиме). Вы получаете больший контроль над тем, что отображают браузеры.

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

Использование srcset

Здесь мы сделали копию изображения по умолчанию (src) в низком разрешении (1×). Сделать изображением по умолчанию самый маленький / самый быстрый ресурс обычно является разумным выбором. Мы также предоставляем 2х версию. Если браузер знает, что он находится на дисплее с более высокой плотностью пикселей (2x), он будет использовать это изображение.

Руководство по синтаксису адаптивных изображений в HTML

Вы можете создать столько вариантов плотности пикселей, сколько захотите.

Хотя это круто и полезно, x-дескрипторы учитывают лишь небольшой процент использования адаптивных изображений. Почему? Они позволяют браузерам адаптироваться только на основе одного: плотности пикселей. Однако часто адаптивные изображения используются в адаптивных макетах, а размер макета изображения уменьшается и растягивается вместе с областью просмотра. В таких ситуациях браузер должен принимать решения на основе двух вещей: плотность пикселей на экране и размер макета изображения. Вот тут-то в игру вступают дескриптор w и атрибут sizes, которые мы рассмотрим в следующем разделе.

Использование srcset/ w+sizes

Это полезная вещь. На нее приходится около 85% использования адаптивных изображений в Интернете. Мы по-прежнему предоставляем одно и то же изображение в разных размерах, только мы даем браузеру больше информации, чтобы он мог адаптироваться на основе как плотности пикселей, так и размера макета.

Мы по-прежнему предоставляем несколько копий одного изображения и позволяем браузеру выбрать наиболее подходящую. Но вместо того, чтобы маркировать их по плотности пикселей (x), мы помечаем их шириной ресурса, используя w-дескрипторы. Так что если baby-s.jpg имеет размер 300 × 450, мы помечаем его как 300w.

Использование srcset с дескрипторами ширины (w) означает, что его необходимо будет связать с атрибутом sizes, чтобы браузер знал, сколько места будет занимать изображение. Без этой информации браузеры не смогут сделать разумный выбор.

Руководство по синтаксису адаптивных изображений в HTML

Указание точного sizes

Указание атрибутов sizes может стать сложным. Атрибут sizes описывает ширину, с которой изображение будет отображаться в макете вашего конкретного сайта, это означает, что он тесно связан с CSS. Ширина рендеринга изображений зависит от макета, а не только от области просмотра!

Давайте рассмотрим на довольно простой макет с тремя контрольными точками.

Котрольные точки задаются в CSS медиа-запросами:

Размер изображения разный в каждой контрольной точке. Вот разбивка всех фрагментов, которые влияют на ширину макета изображения в наибольшей контрольной точке (когда область просмотра шире, чем 700px):

Руководство по синтаксису адаптивных изображений в HTML

Ширина изображения равна 100vw минус все явно заданные размеры margin, padding, ширины столбцов и gap.

Уф! Честно говоря, я обнаружил, что задать это все немного сложно, и я сделал кучу ошибок, когда создавал этот алгоритм. В итоге у меня получилось это:

Атрибут sizes, который дает браузеру ширину изображения во всех трех контрольных точках, факторинг в сетке макета, и окружающие gap, margin и padding, все это в конечном итоге влияет на ширину изображения.

Но подождите! Барабанная дробь! Это все еще неверно. Я не понимаю, почему именно, потому что для меня это выглядит как 100% описывающее то, что происходит в макете CSS. Но это неправильно, потому что RespImageLint Мартина Освёгера говорит так. Запуск этого инструмента для изолированной демо-версии, не показывает других проблем, кроме того факта, что атрибут sizes является неправильным для некоторых размеров области просмотра, и он должен быть:

Я не знаю, как это рассчитывается, и это совершенно невозможно сделать вручную, но это точно. Инструмент Мартина программно изменяет размер страницы и записывает атрибут sizes, который описывает фактическую наблюдаемую ширину изображения в широком диапазоне размеров области просмотра. Это математика, которую обрабатывают компьютеры, так что это правильно. Поэтому, если вам нужен сверхточный sizes атрибут, я бы рекомендовал сначала поставить неправильный атрибут, запустить этот инструмент и скопировать правильный.

Более простой sizes

Абстрагируя sizes

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

По сути, я говорю об установке значения sizes один раз в переменной и об использовании этой переменной во множестве разных элементов <img> на сайте. Нативный HTML не дает такой возможности, но любой внутренний язык да; например, константы PHP, переменные конфигурации Rails, context API React, используемый для установки глобальной переменной состояния, или переменные в языке шаблонов, таком как Liquid, могут быть использованы для абстрагирования sizes.

«Выбор браузера»

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

Сначала математика довольно проста. Скажем, вы собираетесь вывести изображение шириной 40vw в окне просмотра шириной 1200px на экране с плотностью пикселей 2x. Идеальное изображение будет иметь ширину 960 пикселей, поэтому браузер будет искать самое близкое, что у него есть. Браузер всегда рассчитывает размер цели, который он предпочел бы, исходя из ситуации области просмотра и плотности пикселей, а также того, что он знает sizes, и сравнивает эту цель с тем, из чего он выбирает в srcset. Однако то, как браузеры делают выбор, может стать немного странным.

Браузер может учесть больше вещей в этом уравнении, если захочет. Например, он мог бы учитывать текущие скорости сети пользователя или то, переключил ли пользователь какое-либо предпочтение «сохранения данных». Я не уверен, что какие-либо браузеры действительно делают подобные вещи, но они могут сделать это, если захотят, так как спецификация это определяет. То, что иногда выбирают некоторые браузеры, это извлечение из кеша. Если математика показывает, что они должны использовать изображение с 300px, но у них уже есть 600px в локальном кеше, они просто будут использовать это. Умно. В этом заключается сила синтаксиса srcset / sizes. Это также объясняет, почему вам всегда стоит использовать в srcset разные размеры одного и того же изображения: у вас нет возможности узнать, какое изображение будет выбрано. Это выбор браузера.

Это странно. Разве браузер уже не знает это все?

Вы можете подумать: «Хм, почему я должен сообщать браузеру, насколько велико изображение, разве он сам не знает этого?» Ну, он знает, но только после того, как вы загрузили HTML и CSS и выложили все. Атрибут sizes связан со скоростью. Он дает браузеру достаточно информации, чтобы сделать правильный выбор сразу, как только он увидит ваш img.

Читайте также: