От автора: создать гибкие изображения, когда они находятся в макете, в наше время достаточно просто. Однако в более сложных интерфейсах нам часто приходится размещать изображения внутри адаптивных элементов, таких как эта карточка ниже.
Пока давайте предположим, что это изображение не является семантическим содержимым, а лишь украшением. Это подходящее использование для фонового изображения. И поскольку в этом контексте изображение содержит объект, мы не можем допустить, чтобы какие-либо части были обрезаны, когда оно адаптируется, поэтому мы выбрали background-size: contain.
Вот где все начинает усложняться: на мобильных устройствах эта карточка меняет направление и становится вертикальной с изображением сверху. Мы можем добиться этого с помощью любой техники CSS-верстки, и, вероятно, лучше всего использовать CSS-сетку или flexbox.
Но когда мы тестируем маленькие экраны из-за свойства contain, мы получаем следующее:
Это не очень красиво. Размер изображения изменяется, чтобы сохранить его пропорции, не обрезая детали, и если изображение имеет важное содержимое и не должно быть обрезано, мы не можем изменить значение background-size на cover.
На этом этапе наша следующая попытка может быть вам знакома: позиционировать изображение встроенным вместо применения, как фон. На настольном устройстве это работает нормально:
На мобильном телефоне тоже неплохо:
Но на меньших экранах из-за всех фиксированных размеров пропорции изображения искажаются.
Мы могли бы часами возиться с изображением, карточкой, гибкими свойствами, переходя туда-сюда. Или мы могли бы …
Отделить основное содержимое от фона
Это основа для получения большей гибкости и устойчивости, когда дело доходит до адаптивных изображений. Это может быть невозможно в 100% случаев, но во многих случаях этого можно достигнуть с небольшими усилиями с точки зрения дизайна, особенно если этот подход планируется заранее.
Для нашей следующей итерации мы помещаем изображение клубники на прозрачный фон и устанавливаем синий цвет в растровом изображении с помощью CSS. Поэкспериментируйте с размерами области просмотра в этой демонстрации, настроив размер пространства образца!
Глядя более подробно на стили, обратите внимание, что мы также добавили отступы в div, который содержит изображение, чтобы клубника не подходила слишком близко к краям. Мы имеем полный контроль над тем, насколько близко или далеко они будут, через эти отступы.
Обратите внимание, что мы также используем отрицательные поля, чтобы компенсировать отступы внешней оболочки карточки, в противном случае мы получили бы пустое пространство вокруг изображения.
Используйте свойство object-fit для встроенных изображений
Хотя предыдущая демоверсия работает, мы все же можем улучшить этот подход. До сих пор мы предполагали, что изображение было несемантическим содержимым, но при таком макете также вероятно, что изображение может быть не просто украшением.
Если это так, мы определенно не хотим, чтобы изображение было обрезано, потому что это по существу приведет к потере данных. Семантически лучше сделать изображение встроенным, чтобы предотвратить это, и мы можем использовать свойство object-fit.
Мы извлекли клубнику из фона, и теперь это встроенный элемент img, но мы сохранили цвет фона в том же самом div изображения.
Наконец, объединение object-fit: contain со 100% шириной позволяет изменить размер окна и сохранить соотношение сторон клубники. Однако такой подход заключается в том, что нам нужно установить фиксированную высоту для изображения в настольной версии — в противном случае оно будет подстраиваться под пропорции установленной ширины (и ее уменьшение приведет к изменению макета). Это может сделать вещи слишком ограниченными, если нам нужно будет генерировать эти карточки с переменным количеством текста, разбитым на несколько строк.
Скоро выйдет aspect-ratio
Решение проблемы может быть уже на подходе, с помощью готовящегося свойства aspect-ratio. Оно позволит установить фиксированное соотношение для элемента, например так:
1 2 3 |
.el { aspect-ratio: 16 / 9; } |
Это означает, что мы сможем устранить фиксированную высоту и заменить ее расчетным соотношением сторон. Например, размеры в настольной контрольной точке последнего примера выглядят так:
1 2 3 4 5 |
.image { /* ... */ height: 184px; width: 318px; } |
С помощью aspect-ratio мы можем удалить объявление высоты и выполнить математические вычисления, чтобы получить наиболее близкое отношение, равное 184:
1 2 3 4 5 6 |
.image { /* ... */ width: 318px; /* Base width */ height: unset; /* Resets the height that was set outside the media query */ aspect-ratio: 159 / 92; /* Amounts close to a 184px height */ } |
В конце концов, есть несколько способов получить надежно адаптивное изображения в макете с изменяющимися пропорциями. Однако трюк, чтобы сделать эту работу легче — и лучше — не обязательно должен быть связан с CSS; это может быть так же просто, как адаптировать изображения, будь то путем отделения переднего плана от фона (как мы это делали) или обрезки конкретных изображений, которые все равно будут выглядеть нормально, если обрезать значительную часть краев.
Автор: Lari Maza
Источник: //css-tricks.com
Редакция: Команда webformyself.