Skip to main content

CSS Object-fit та Object-position

object-fit керує тим, як замінювані елементи (<img>, <video>) масштабуються всередині контейнера. object-position задає позицію масштабованого контенту всередині того ж простору.

Теорія

TL;DR

  • Уяви фоторамку: cover обрізає фото, щоб заповнити рамку; contain стискає так, щоб все було видно, але з пустим місцем по боках
  • object-fit відповідає за стратегію масштабування; object-position за вирівнювання (схожа логіка на background-position, але для <img>)
  • Працює тільки на замінюваних елементах (<img>, <video>), не на <div>
  • За замовчуванням стоїть fill, який розтягує зображення і спотворює пропорції
  • Правило вибору: для hero-банерів використовуй cover; для мініатюр - contain

Швидкий приклад

css
.card-image { width: 300px; height: 200px; object-fit: cover; /* Масштабуємо і обрізаємо зайве */ object-position: center; /* Центр зображення залишається у кадрі */ }

Квадратне зображення 400x400, вставлене в блок 300x200, масштабується вгору, рівномірно обрізається зверху і знизу, і залишається відцентрованим. Без спотворень. Це базовий патерн.

Головна різниця

object-fit вибирає стратегію масштабування: розтягнути, вмістити повністю, обрізати до заповнення або залишити оригінальний розмір. object-position потім зсуває результат всередині блоку за координатами 50% 30% або ключовими словами top right. Без явного object-fit браузер використовує fill, який ігнорує пропорції. object-position має ефект тільки після того, як застосовано fit.

Коли що використовувати

  • Hero-банер без спотворень: object-fit: cover; object-position: center
  • Мініатюри, де видно все зображення: object-fit: contain; object-position: center
  • Аватар з обрізанням по обличчю: object-fit: cover; object-position: 50% 30% (очі ближче до верху)
  • Відео в letterbox режимі: object-fit: contain
  • Логотип в оригінальному розмірі без збільшення: object-fit: none

Таблиця порівняння

ЗначенняМасштабуванняПропорціїОбрізанняЗаповнює блокКоли використовувати
fillРозтягує до 100%СпотворюєНіТакПіксель-арт, де спотворення допустиме
containВміщує повністюЗберігаєНі (letterbox)НіМініатюри, перегляд повного зображення
coverМасштабує до заповненняЗберігаєТак (overflow hidden)ТакHero-зображення, картки, аватари
noneБез масштабуванняЗберігаєМожливоНіЛоготипи, важливий оригінальний розмір
scale-downОбмежує до оригінального розміруЗберігаєНіНіВеликі зображення, які не потрібно збільшувати

Типові помилки

1. Застосування object-fit до <div>

css
/* Неправильно: object-fit ігнорується на не-замінюваних елементах */ .box { object-fit: cover; background: url(img.jpg); /* Не має жодного ефекту */ } /* Правильно: для div використовуй background-size */ .box { background: url(img.jpg) center / cover no-repeat; }

2. Відсутність width і height на зображенні

css
/* Неправильно: без розмірів object-fit не знає з чим працювати */ .container { height: 200px; } img { object-fit: cover; } /* Правильно */ img { width: 100%; height: 100%; object-fit: cover; }

Зображенню потрібні явні розміри. Без них воно відображається у своїх природних розмірах і object-fit нічого не робить видимого. Це найпоширеніший баг з цим пропсом.

3. Портретне зображення в горизонтальному блоці з cover - несподіване обрізання

cover обрізає той вимір, що виходить за межі блоку. Висока вертикальна фотографія в широкому горизонтальному блоці втратить боки. Рішення: object-position: center top, щоб голова залишилась у кадрі.

Де зустрічається в реальному коді

  • Next.js <Image> з fill layout використовує object-fit: cover всередині для адаптивного кадрування
  • TailwindCSS має класи object-cover, object-contain, object-center, які використовуються в сотнях тисяч проєктів
  • Video.js використовує object-fit: contain для адаптивних відеовставок
  • Для декоративних фонів на div використовуй background-size: cover. object-* призначений для семантичних зображень з атрибутом alt

Можливі питання на співбесіді

Q: Яке значення object-fit стоїть за замовчуванням?
A: fill. Воно розтягує зображення точно під width і height, спотворюючи пропорції.

Q: Чим відрізняється object-position: bottom від object-position: 50% 100%?
A: Нічим. Ключові слова CSS відображаються у відсотки: top = 50% 0%, bottom = 50% 100%, center = 50% 50%.

Q: Чи працює object-fit на <canvas> або <svg>?
A: На <svg>, вставленому як замінюваний елемент через <img src="icon.svg">, так. <canvas> потребує ручного масштабування в JavaScript.

Q: Що відбувається, коли браузер ще не знає розміри зображення, наприклад при lazy load?
A: Браузер використовує розмір за замовчуванням 300x150 пікселів. object-fit обчислюється на цій основі, а потім перераховується після завантаження. Без aspect-ratio на контейнері отримуєш зміщення layout. Рішення: поєднуй object-fit з aspect-ratio на обгортці.

Приклади

Hero-банер з cover

css
.hero { width: 100%; height: 500px; overflow: hidden; } .hero img { width: 100%; height: 100%; object-fit: cover; /* Заповнення без спотворення */ object-position: center; /* Центруємо точку обрізання */ }

Зображення заповнює всю ширину на будь-якому viewport. Які б не були оригінальні розміри, браузер масштабує і обрізає автоматично. Це патерн за кожним повноширинним банером.

Аватар користувача з фокусом на обличчі

css
.avatar { width: 80px; height: 80px; border-radius: 50%; overflow: hidden; } .avatar img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%; /* Точка обрізання у верхній третині - очі залишаються у колі */ }

Значення 30% від верху зсуває кадрування вгору. Обличчя залишається у центрі кола замість чола або підборіддя.

Галерея із зафіксованими пропорціями

css
.gallery-item { width: 100%; aspect-ratio: 16 / 9; /* Форма блоку не залежить від розмірів зображення */ overflow: hidden; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; object-position: center; transition: transform 0.3s; } .gallery-item:hover img { transform: scale(1.05); }

Поєднання aspect-ratio з object-fit: cover прибирає потребу у фіксованих значеннях height. Блок зберігає форму 16:9; зображення заповнює його на будь-якому viewport.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?