Когда вы верстаете адаптивный сайт, вы наверняка задумываетесь о том, как должны выглядеть ваши изображения. И тут вас должны интересовать 2 аспекта:

  1. Насколько изображения вписываются в дизайн и соответствуют макету сайта
  2. Насколько быстро загружаются фото в зависимости от размера экрана и скорости Интернета пользователя.

Давайте попробуем разобраться в этих вопросах, используя для этой цели теги <img> и <picture>.

Отзывчивое изображение с помощью тега <img>

Вы наверняка знаете, что изображения добавляются на страницу с помощью тега <img>:

Стандартный подход для обеспечения отзывчивости, или адаптивности изображения в этом случае - это CSS-код, который не дает картинке выйти за пределы родительского контейнера, а наоборот, заставляет ее уменьшаться вместе с родительским элементом:

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

Отзывчивые изображения для всех экранов

Используем атрибут srcset для определения размеров изображений для разных экранов

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

<img srcset="" src="" alt="">

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

Несколько замечаний насчет srcset:

  • srcset — это замена атрибута src , но при этом он имеет больший приоритет, чем src.
  • атрибут src должен быть всегда указан, т.к. это необходимо для поисковых роботов.
  • атрибутsrc будет использован, только если браузер не поддерживает srcset.
  • В браузерах Chrome  и Firefox srcset обрабатывается несколько иначе, хотя и подобным образом. Например, Firefox может уменьшать размер изображения при уменьшении ширины экрана, а Chrome, если уже загрузил больший размер, то будет использовать его и на меньших разрешениях. Просчет того, какую картинку выбрать также чуть-чуть отличается.

Divice pixel ratio - соотношение пикселей экрана и ширины устройства

Телефоны сегодня, как и 6-8 лет, назад имеют физический размер в 320-480px, причем многие из них, включая популярные iPhon-ы и Samsung-и, имеют разрешение устройства 360-414px, т.е. не слишком большие размеры, на которые с точки зрения верстки имеет смысл подгружать маленькие изображения. Однако ситуация с экранами сильно изменилась в сторону изменения количества отображаемых ими пикселей с момента выпуска компанией Apple retina-дисплеев. Теперь флагманы многих компаний имеют соотношение пикселей экрана и реального устройства (pixel ratio) 4:1, во многих смартфонах средней ценовой категории это соотношение 3:1, и даже в дешевых телефонах нередко встречается pixel ratio в виде 2:1. Посмотрите сами, какое соотношение у вашего устройства, перейдя на сайт mydevice.io.

pixel ratio 2x 3x

К чему такое длинное вступление? Оно важно для понимания того, что современные телефоны готовы загрузить картинки намного больше их физического разрешения. То есть для Apple iPhone 11 с pixel ratio 2x и  шириной 414px нужно изображение размером

414px*2 = 828px

Для Apple iPhone 11 Pro Max с pixel ratio 3x и  шириной 414px нужно изображение размером

414px*3 = 1242px

Для браузера на компьютере вы можете узнать текущий pixel ratio, открыв консоль (CTRL +Shift +I), и введя в ней window.devicePixelRatio.

Насчет Device Pixel Ratio почитайте еще здесь и здесь.

Что касается размеров изображений, то вы можете нарезать их в разных размерах, но после этого внимательно посмотрите на вес этих изображений. Довольно часто ваш выигрыш может составлять 2-3 кб, но стоит ли это отдельного запроса на сервер? Поэтому имеет смысл остановиться на 2-3 базовых размерах, а не множить их в гонке за максимальной оптимизацией.

Переключение ширины

Когда изображение загружается только с обычным атрибутом src, браузер не знает, насколько оно широко, до тех пор, пока оно не будет загружено. Если вы добавляете в тег <img> атрибуты width и/или height, браузер сможет выделить сразу необходимое количество пикселей для картинки.  Когда вы используете атрибут srcset, вы можете сказать браузеру, насколько широко каждое из нужных изображений заранее. Затем он может использовать эту информацию для загрузки наиболее подходящего изображения в зависимости от размера области просмотра в данный момент.

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

Есть еще один подход к указанию атрибутов для изображения, заточенный под SEO. Он был предложен в этом видео и подразумевает, что мы указываем в атрибуте src тега <img> путь к самому большому и качественному изображению, которое выведет нашу страницу на первые позиции поиска по картинкам такого характера, а в атрибуте srcset указываем набор (иначе массив) путей к файлам, которые будут реально загружены для пользователей на различных устройствах в зависимости от их ширины экранов. То есть самое большое изображение "увидит" поисковая система и старый браузер.

Пример кода:

Здесь в srcset мы указываем через запятую путь к файлу изображения, а затем через пробел указываем ширину изображения 320w или 640w, заменяя единицы измерения px на w.

Реальный пример на codepen.io, который вы можете протестировать в отдельной вкладке на разных разрешениях экрана. Это же можно сделать, включая/выключая вкладку HTML, например. Еще один способ - более интересный с точки зрения наборов разрешений экранов - протестировать пример, введя ссылку на сайте http://ru.infobyip.com/testwebsiteresolution.php или на сайте https://tools.saitreport.ru/webpage-screen-resolution-simulator.

Кстати, обязательным для работоспособности всех примеров является наличие meta-тега viewport в блоке <head>:

Протестируйте пример:

See the Pen img with srcset by Elen (@ambassador) on CodePen.

В зависимости от разрешений вы должны увидеть такие фото с собаками. Наведите на изображение - и увидите при каком разрешении оно должно появиться.


Не увидим совсем мы содержимого атрибута src  файла с такой собакой, если у нас новый браузер с поддержкой srcset.

Переключение плотности пикселей

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

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

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

See the Pen img srcset by Elen (@ambassador) on CodePen.

Представители кошачьих в зависимости от плотности пикселей экрана в порядке возрастания от 1x до 4x:

Использование атрибута sizes для управления макетом изображения

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

Неважно, какой файл изображения браузер выберет для загрузки из вашего srcset, он будет отображаться с шириной, указанной вами в размерах.

Например, если вы хотите, чтобы ваше изображение всегда отображалось на 80% ширины области просмотра, используйте такой код:

Примечание: процентные значения в sizes недопустимы, но единицы vw отталкиваются от ширина области просмотра.

В этом примере браузер по-прежнему будет выбирать между маленьким, средним и большим изображениями в зависимости от размера области просмотра, но какое бы изображение ни было выбрано, оно будет отображаться с шириной 80vw.

See the Pen Image width &amp; height in srcset by Elen (@ambassador) on CodePen.

Перейдите на codepen.io, начните просмотр с небольшого размера области просмотра и постепенно его увеличивайте. Вы увидите, что изображение будет всегда меньше области просмотра.

Добавление медиа-условий в атрибут sizes

В нашем примере выше мы использовали только одно значение в атрибуте размеров, но вы можете изменить вид изображения, добавив медиа-условия. Медиа-условия - это использование медиа-запросов при оценке размеров картинки. Тут вы можете по-разному размещать свои изображения в зависимости от ширины области просмотра (viewport-a). С точки зрения английского языка  ширина области просмотра переводится, как viewport width, поэтому и единицы измерений для указания ширины изображения будут vw.

Например, мы можем задать изображению ширину в 80vw, а слева и справа от него оставить свободное место за счет margin: auto, как в нашем предыдущем примере. Но теперь мы будем изменять ширину изображения в зависимости от области просмотра,  если она достаточно широкая, например, минимум 60rem.

Мы можем добиться этого, добавив условие, подобное медиа-запросу (min-width: 60rem) , указывая его перед размером 80vw, например, так:

Теперь изображение будет иметь размер в 80vw, только если ширина области просмотра составляет не менее 60rem.

В том случае, если область просмотра не соответствует медиа-условию, мы можем использовать для нашего изображения по умолчанию ширину в 100vw, т.е. на все доступное пространство области просмотра. Для значения по умолчанию в атрибуте sizes мы просто указываем значение 100vw после запятой:

Можно добавлять другие размеры и медиа-условия для разрешения экрана в пикселях. Например, для min-width: 1000px (большие экраны) установим 60vw , для средних  (min-width: 575px) используем 90vw , а для маленьких -  100vw:

Изменяйте размеры области просмотра от маленькой до большой и смотрите , какие картинки загружаются.

See the Pen Image width &amp; height in srcset by Elen (@ambassador) on CodePen.

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

Тег <picture>

<picture> <source srcset="" ...> <picture>

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

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

Когда использовать тег <picture>

Вариант 1. Когда нужно указать размены картинок как замену атрибуту srcset

Допустим, вам просто удобнее разбираться с синтаксисом с вариантами картинок и их размерами в этом варианте.

See the Pen Tag picture + source with srcset and sizes by Elen (@ambassador) on CodePen.

Вариант 2. Когда вам нужно указать разные типы изображений

Не секрет, что форматы WEBP и AVIF уже являются более предпочтительными, чем JPG, PNG или сильно утративший популярность GIF за счет своих алгоритмов сжатия. И, если  WEBP поддерживается уже очень хорошо, то AVIF пока несколько от него отстает, хотя разница всего в 4%.

Однако для уверенности в загрузке нужного вам формата лучше написать такой код:

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

Несколько замечаний:

  • Расширение изображения, которое вы указываете в <source>, должно соответствовать типу этого изображения, указанному в type.
  • Не используйте атрибут media, если вам не нужно изменять размеры изображений.
  • Можно использовать srcset и sizes, как для тега img.

Для изображений разных форматов и плотности пикселов:

Вариант 3. При указании для каждого source отдельного атрибута media

Отличный вариант, очень предсказуемо работает. Правила media указываются так же, как и в CSS. Например:

Пример в действии (перейдите на codepen.io и изменяйте размер экрана):

See the Pen Tag picture + source with media by Elen (@ambassador)  on CodePen.

Вариант 4. Когда вам нужно изменить изображение для портретной и альбомной ориентации

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

Работающий пример (тест на отдельной странице):

See the Pen Tag picture + source with media by Elen (@ambassador) on CodePen.

Более сложный пример:

Проблемы с SEO для  тега <picture>

Как мы с вами увидели, тега <picture> отлично справляется с разными форматами изображений, их размерами и добавлением фото в зависимости от ориентации девайса. Достаточно просто перечислить внутри тегов source все нужные изображения (avif, webp, jpeg или png)  - и браузер сам решит, что отображать пользователю.

Однако одним из недостатков с точки зрения Google PageSpeed Insight является размер структуры DOM вашей страницы. Рекомендуемая граница DOM-дерева для страницы не должна превышать 1500 узлов. Это то, что желательно иметь. На реальных сайтах часто эта граница превышена. А каждый узел DOM-дерева – это расход памяти и замедление скриптов. С точки зрения использования тега <picture> в структуре DOM - это добавление не одного, а как минимум 3-х узлов, а значит  увеличение DOM-дерева.

Так что пока этот тег имеет смысл использовать для страниц с небольшим количеством контента, а в <img> стоит добавлять srcset, если нужно управлять размерами загружаемой картинки.

Бонус

Ниже вы найдете пример, изменяющий изображения с помощью css-переменных в зависимости от разрешения экрана. Однако это уже работа CSS, а не HTML, теги <img> здесь не при чем, тут идет работа с фоновыми изображениями на основе свойства background-image.

See the Pen Hero Section With Mutiple Background Images - CSS Variables by Envato Tuts+ (@tutsplus) on CodePen.

Автор: Админ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *