Адаптивные изображения в макете веб-страницы разных пропорций

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

Пока что давайте предположим, что эта картинка – не семантический элемент, а декоративный. Тогда нам будет удобно использовать свойство background-image. Так как в нашем случае изображение содержит объект, нельзя, чтобы какие-то его части обрезались при растяжении окна. Поэтому мы используем свойство background-size: contain.

Вот здесь начинаются сложности: на мобильных устройствах формат карточки меняется на вертикальный и картинка уходит наверх. Мы можем добиться этого, используя любой метод вёрстки CSS. Лучше всего это получается с помощью сетки (grid или flexbox).

Однако если мы протестируем этот способ на маленьких экранах, из-за свойства contain, получим следующее:

Эй, вернись на место!

Выглядит не очень красиво. Картинка поменяла свой размер, чтобы сохранить соотношение сторон без обрезания краёв. Если изображение важное и не должно быть обрезано, мы не можем изменить значение background-size на cover.

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

На экране компьютера работает нормально:

На мобильных устройствах тоже неплохо:

Но на маленьких экранах, из-за всех фиксированных размеров, пропорции изображения искажаются.

Хмм… в растянутом виде эта клубника выглядит не так аппетитно.

Мы можем часами возиться с изображением, карточкой, свойствами сетки; меняя то одно, то другое. Или же можем…

Отделить основное содержимое от фона

Это основа для получения большей эластичности и устойчивости, когда дело касается адаптивных изображений. Возможно, это будет работать не в 100% случаев, но во многих из них. Этого можно достичь, приложив немного усилий к дизайну объектов; особенно, если такой подход был спланирован заранее.

Повторяем всё сначала: помещаем изображение с клубникой на прозрачный фон и устанавливаем с помощью CSS тот голубой цвет, который был на растровой картинке. Теперь вы можете сами поиграться с размерами окна просмотра в приведенной ниже демо — версии!

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

Обратите внимание на то, что мы также используем отрицательное значение margin, чтобы компенсировать padding элемента, содержащего карточку, иначе у нас появится белое пространство по всему периметру изображения.

Используйте свойство object-fit для строчных картинок

Несмотря на то, что демо-версия страницы работает исправно, мы всё ещё можем улучшить используемый подход. До этого момента мы предполагали, что картинка – несемантический объект. Но на подобном макете веб-страницы изображение может быть чем-то большим, чем просто декоративным элементом.

Если это наш случай, то мы определённо не хотим, чтобы картинка была обрезана, ведь это приведёт к существенной потере данных. Чтобы это предотвратить, семантически будет лучше разместить изображение в строке, а не на фоне. И мы можем осуществить это с помощью свойства object-fit.

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

Наконец, объединив свойство object-fit: contain и ширину, равную 100%, мы получаем возможность изменить размер окна и сохранить соотношение сторон клубники. Однако, выбирая такой метод, мы должны установить фиксированную высоту изображения в версии для ПК, иначе она будет пропорциональна установленной ширине (а уменьшение ширины повредит макет веб-страницы). Это может слишком ограничить нас, если нужно создать карточки с переменным объемом текста, разбитым на несколько строк.

Скоро появится свойство aspect-ratio

Решением проблемы, описанной выше, может стать свойство aspect-ratio, которое должно появиться в ближайшем будущем. Оно позволит устанавливать фиксированное соотношение сторон для элемента, как здесь:

.el {
  aspect-ratio: 16 / 9;
}

Это значит, что мы сможем избавиться от фиксированной высоты и заменить её рассчитанным соотношением сторон. Например, размеры контрольной точки для ПК в нашем последнем примере выглядели так:

.image {
  /* ... */
  height: 184px;
  width: 318px;
}

С помощью свойства aspect-ratio мы сможем не объявлять значение высоты, а рассчитать соотношение сторон, близкое к 184px.

.image {
  /* ... */
  width: 318px; /* Ширина основания */
  height: unset; /* Сбрасывает высоту, установленную вне медиа-запроса */
  aspect-ratio: 159 / 92; /* Значения, которые ближе всего к высоте 184px */
}

Как видите, существует сразу несколько способов создать адаптивные изображения в макете веб-страницы с разными пропорциями. В любом случае, это можно сделать проще (и качественнее) не только с помощью CSS; например, можно отделить передний план от фона (как мы и сделали) или выбирать определённые картинки, которые будут выглядеть нормально, даже с обрезанными краями.

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

Пожалуйста, оставляйте свои мнения по текущей теме статьи. За комментарии, лайки, отклики, дизлайки, подписки огромное вам спасибо!

Наталья Кайдаавтор-переводчик статьи «Fluid Images in a Variable Proportion Layout»