Краткий обзор «object-fit» и «object-position»
Перевод статьи A Quick Overview of `object-fit` and `object-position с сайта css-tricks.com для css-live.ru. Автор — Роберт Рендли.
Последнее время object-fit
и object-position
— мои любимые CSS-свойства. С ними разработчики могут управлять содержимым внутри img
или video
, подобно манипулированию содержимым background
с помощью background-position
и background-size
.
Для начала, подробнее про object-fit
Это свойство определяет, как элемент вроде img
подстраивается под доступные ширину и высоту своего содержимого. С object-fit
можно приказать содержимому заполнить этот бокс различными способами, например, «сохранить эти пропорции!» или «растянуться и занять как можно больше места!»
Вот пример:
Это изображение 400х260px. Если добавить к нему…
img { width: 200px; height: 300px; }
… то в итоге получим неуклюжее искажение, поскольку изображение сплющивается, чтобы уместиться в эти рамки:
Содержание в нашем img
займёт всё доступное пространство в своём новом боксе, созданном при изменении его высоты и ширины, «ломая» тем самым его исходные пропорции.
Чтобы и сохранить пропорции изображения и заполнить всю доступную область, воспользуемся object-fit
:
.cover { object-fit: cover; }
Слева исходное изображение, а справа — изображение обрезанное по бокам, которое теперь сохраняет наши пропорции! Может в таком масштабе это и не выглядит впечатляющим, но как только мы столкнёмся с разработкой более реалистичных интерфейсов, вот тогда-то object-fit
и проявит себя во всей красе.
Возьмём другой пример:
Здесь у нас два изображения, которые должны занимать 50% ширины окна браузера (чтобы они стояли бок о бок) и 100% высоты. Для этого воспользуемся единицами области просмотра.
img { height: 100vh; width: 50vw; }
Проблема всплывает, когда при изменении размера экрана меняются и пропорции изображения, что приводит к всевозможным странностям. А нам бы хотелось сохранить их пропорции, как и в предыдущем демо, так что для этого можно использовать тот же метод. object-fit: cover
, выручай!
Попробуйте снова изменить размер экрана. Странности с пропорциями исчезли, так ведь? Это также весьма полезно для изображений с различными размерами, поскольку они фактически будут обрезаны по границам бокса.
cover
— лишь одно из многих значений для object-fit
, о которых более подробно можно почитать в справочнике, но пока что это единственное значение, которое кажется мне наиболее полезным для повседневной разработки интерфейсов.
Перейдём к следующему из моих любимых свойств: object-position
.
Воспользуемся уже знакомым изображением и этими стилями:
img { background: yellow; height: 180px; object-fit: none; }
Здесь стоит отметить пару вещей: для правильной работы object-position
нужно объявить размеры для изображения, а чтобы изображение не заполняло весь бокс (как это происходит по умолчанию), а его можно было сдвинуть, нужно установить ему object-fit: none
. Это может показаться странным, но всё дело в том, что по умолчанию для изображения устанавливается object-fit: fill
, даже если не объявлять его специально.
Что касается поведения по умолчанию, без значения object-position
центрирует все объекты по горизонтали и вертикали:
img { background: yellow; height: 180px; object-fit: none; object-position: 50% 50%; /* Даже если это не объявлять, изображение всё равно отцентрируется. */ }
Первое значение смещает изображение влево или вправо, а второе — вверх или вниз. Здесь можно поэкспериментировать с этими значениями:
Мы можем даже «протолкнуть» изображение внутрь его области контента, так что можно будет увидеть background-color
, который мы задали раньше
Но насколько это полезно? Хороший вопрос! Вот в недавнем проекте мне потребовалось сдвинуть к центру конкретный участок изображения, и тем самым привлечь внимание читателя. Загрузка нового изображения не требуется, поэтому в этом случае не понадобится элемент <picture>
, всё, что мы хотели — немного сдвинуть изображение.
Помимо смещения фокуса на нужную часть изображения, не очень представляю, для чего еще это может быть полезно на практике. Но я повозился с object-position
, чтобы продемонстрировать, как можно скрыть части изображения, а затем по клику показывать его по кусочкам, как в этом демо:
Я не эспериментировал, как и для чего можно использовать это для элементов <video>
. Может быть, видео на весь экран, заполняющее его без черных полос по краям? Чтобы полностью раскрыть потенциал этих свойств, изучить предстоит ещё очень много.
Что с поддержкой?
В целом, неплохо!
object-fit
поддерживается везде, кроме IE/Edge. А object-position
поддерживается везде, кроме Safari и IE/Edge.
P.S. Это тоже может быть интересно:
Сталкивался с такой задачей. Есть груда html-ок статей, в которых есть img-ы, с указанными width и height. Большая часть из них по ширине совпадает с блоком, в котором эти статьи показываются. Но вдруг возникает необходимость в некоторых ситуациях показывать боковую колонку и ширина контента резко уменьшается.
Задача: используя CSS добиться max-width: 100%, но так, чтобы не потерять пропорции. Первое что приходит в голову, это влепить height: auto… Но в таком случае мы 1) получаются прыгающий контент, пока рисунки грузятся 2) если пропорции изначально нарушены, и так нужно, то мы его теряем. Фиг с ней со второй проблемой, но вот первая уже действительно печалит.