Полное руководство по отзывчивым изображениям!

Короткое введение в экраны повышенной плотности

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

  • разрешение в CSS предназначено для измерений на нашем сайте;
  • разрешение экрана это фактическое количество пикселей на экране.
  • Разрешение экрана — 1440 на 3040 пикселей
  • Разрешения в CSS — 360 на 760 пикселей
  • Плотность дисплея — 4х (по 4 физических пикселя на один CSS-пиксель)

Метод описания плотности экрана

Этот метод подходит для изображений, размер которых фиксирован на экранах повышенной плотности. Это значит, что на некоторых экранах для изображений с размером 200 пикселей в CSS/HTML мы можем загрузить картинку в 600 пикселей — или большего размера— потому что на экранах повышенной плотности оно будет давать лучший визуальный результат.

<img src="cat-200px.jpg" alt="котик без сахара" width="200"
srcset="cat-200px.jpg 1x,
cat-400px.jpg 2x,
cat-600px.jpg 3x,
cat-800px.jpg 4x">

Метод описания ширины и атрибут sizes

Этот метод подходит для изображений, ширина которых изменяется в зависимости от размера области просмотра и точками останова. Этот приём наиболее распространен на адаптивных сайтах.

Атрибут srcset с описанием ширины

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

Атрибут sizes

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

sizes="(max-width: 399px) 50vw,
(min-width: 400px) and (max-width: 900px) calc(30vw - 40px),
100vw">
<img src="cat.jpg" alt="cat on a watermelon" 
srcset="cat-200px.jpg 200w,
cat-400px.jpg 400w,
cat-600px.jpg 600w" sizes="(max-width:800px) 30vw, 600px">

Элемент <picture>

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

Метод с <picture> для изменения направления изображения

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

Метод изменения направления — разные изображения в зависимости от ширины области просмотра экрана.

Как работает метод изменения направления?

Внутри элемента <picture> мы используем элемент <source>. В каждом элементе <source> мы прописываем два атрибута: media и srcset. Значением атрибута media является медиавыражение. Точно такое же как обычное медиавыражение. И для каждого медиавыражения определяется атрибут srcset.

Элемент source внутри элемента picture указывает на конкретное изображение
  • Если браузер не поддерживает <picture>, то будет использован элемент <img> (например, в случаях IE и Opera mini).
  • Если ни один из элементов <source> не подошёл по условиям, то браузер использует элемент <img>.
  • Атрибут alt для обеспечения доступности можно добавить только на элемент <img>.
<picture>
<source media="(min-width: 600px) and (max-width: 1200px)"
srcset="images/sinai-medium-screen.jpg">
<source media="(min-width: 1201px)"
srcset="images/sinai-large-screen.jpg">
<img src="images/sinai-small-screen.jpg"
alt="Unicorn Pool Float">
</picture>

Метод с использованием <picture> для разных типов файлов

Другая ситуация, в которой очень пригодится элемент <picture>использование типов файлов с изображениями, которые не поддерживаются всеми браузерами. Например, Google создал новый тип файлов со сжатыми изображениями, который называется webp. Webp не поддерживается всеми браузерами. Например, Safari и IE. И снова элемент <picture> спасёт нас, но в другой конфигурации.

Множество типов файлов изображений
<picture>
<source type="image/svg+xml" srcset="logo.svg">
<source type="image/webp" srcset="logo.webp">
<img src="logo.png" alt="investing.com">
</picture>

Отзывчивые картинки в CSS

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

Функция image-set

Параметрами функции image-set являются пары картинок и плотностей. Точно так же как мы указывали это в атрибуте srcset в методе описания плотности экранов. Браузер выберет то изображение, которое соответствует текущему экрану.

background-image: image-set( url("bg.png") 1x,
url("bg-2x.png") 2x );

Браузерная поддержка image-set

Складывается ощущение, что все просто забыли про эту функцию — некоторые браузеры вообще её не поддерживают, для некоторых нужно указывать префикс -webkit. Для максимального покрытия всех возможных браузеров используйте эту функцию так, как указанно в примере ниже:

background-image: url("bg.png"); /* IE / Edge / Firefox *//* Chrome & Opera */
background-image: -webkit-image-set( url("bg.png") 1x,
url("bg-2x.png") 2x);
background-image: image-set( url("bg.png") 1x,
url("bg-2x.png") 2x);

Медиавыражения для определения плотности экрана

Существует два значения медиавыражений, пригодных для адаптивного дизайна: min-resolution и max-resolution. Они также как и image-set, подходят для случаев, когда вы хотите показывать разные изображения в зависимости от плотности экрана устройства. Разница между этими двумя методами в том, что здесь вы можете использовать абсолютно любые стили.

Ожидаемые фичи для отзывчивых изображений

Направление изображения при помощи CSS-функции image()

Как мы видели в методе изменения направления существуют кейсы, в которых мы хотим нарезать изображения по-разному в зависимости от размера области просмотра. В противовес этому методу, использующемуся в HTML, существует спецификация, позволяющая делать это же при помощи CSS!

background-image: image("myimage.webp#xywh=0,20,40,60");

CSS для типов картинок

Как мы уже видели раньше, существуют ситуации, в которых мы должны подгружать разны типы файлов с изображениями в зависимости от поддержки в конкретном браузере. Для этой возможности тоже существует спецификация CSS. И в ней так же используется функция image(), но с немного другим синтаксисом. Мы можем указать внутри функции набор изображений и браузер будет рассматривать их в том порядке, в котором они написаны, и использует первый файл, который сработает.

.help::before {
content: image("try.webp", "try.svg", "try.gif");
}

Заключение

Вот и всё.
Я надеюсь, что вы насладились чтением этой статьи и узнали что-то новое. Если вам понравился этот пост, то я буду очень благодарен за аплодисменты и шеринг :-)

Кто я?

Меня зовут Элад Шехтер, я веб-разработчик, специализирующийся на дизайне и архитектуре CSS и HTML. Я работаю на Investing.com.

Ресурсы

--

--

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Workafrolic (±∞)

Workafrolic (±∞)

3.6K Followers

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC