Skip to content

Все для WordPress, веб-розробки — і не тільки

🎬 Адаптивний відео-фон на CSS: повний посібник з прикладами коду

🎬 Адаптивний відео-фон на CSS: повний посібник з прикладами коду

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

Здається, що для цього потрібен JavaScript, вимірювання viewport і складна математика. Я теж так думав, коли вперше взявся за це завдання. Перепробував calc(), viewport-одиниці, навіть писав скрипт під ресайз, у Firefox працювало, у Chrome розвалювалося, у Safari взагалі мовчало.

А потім виявилося, що в CSS уже кілька років є властивість, яка робить саме те, що нам потрібно, без жодного рядка JS. І сьогодні я покажу, як зібрати повністю адаптивне відео-тло, яке поводиться як background-size: cover, але для живого відео.

💡 Швидкий огляд:

  • Ставимо відео-елемент на фіксоване позиціювання на весь viewport
  • Застосовуємо object-fit cover, відео само підлаштовується, обрізаючи зайве і зберігаючи центр
  • Для старих браузерів тримаємо запасний варіант на медіазапитах і «великому контейнері»
  • Огортаємо все в контейнер, знадобиться для оверлею, кнопок і тексту поверх відео
  • Адаптуємо під мобільні: інше джерело, playsinline і фолбек-картинка

Базовий підхід: фіксоване позиціювання

Будь-яке відео-тло починається з того, що <video> займає всю область перегляду. Робиться це через position: fixed з нульовими відступами:

1#myvid {
2 position: fixed;
3 top: 0;
4 right: 0;
5 bottom: 0;
6 left: 0;
7}

Елемент розтягується рівно на ширину і висоту viewport. Проблема виникає одразу ж: відео майже завжди знято в пропорції 16:9, а екран користувача може бути квадратним, ультрашироким або портретним. Результат, ті самі чорні смуги, які вбивають весь ефект.

Відео 16:9 у квадратному контейнері з чорними смугами

Якщо ви працювали з фоновими зображеннями в CSS, то знаєте: у background-size є значення cover. Воно змушує картинку заповнити контейнер цілком, обрізаючи зайве і зберігаючи пропорції. Такої самої поведінки потрібно від відео. І вона є.

Сучасне рішення: object-fit: cover

Властивість object-fit створена саме для цього. Вона визначає, як заміщуваний елемент (зображення або відео) вписується у свій контейнер, і значення cover працює точно як background-size: cover:

1#myvid {
2 position: fixed;
3 top: 0;
4 right: 0;
5 bottom: 0;
6 left: 0;
7 width: 100%;
8 height: 100%;
9 object-fit: cover;
10}

Відео масштабується так, щоб повністю заповнити контейнер. Якщо пропорції не збігаються, браузер обрізає зайве зверху і знизу (або ліворуч і праворуч) і автоматично центрує результат. Жодних чорних смуг.

Станом на 2026 рік object-fit підтримують 96.39% браузерів глобально (дані Can I Use). Chrome, з версії 32, Firefox, з 36, Safari, з 10, Edge, з 79. Internet Explorer 11 не підтримує, але його ринкова частка прямує до нуля, а термін підтримки минув.

Для абсолютної більшості проєктів цих трьох рядків CSS достатньо. Відео-тло готове.

Проблеми масштабування: що відбувається «під капотом»

Навіть якщо ви використовуєте object-fit, корисно розуміти механіку. Можливі два сценарії:

Два сценарії масштабування відео: переповнення по вертикалі та горизонталі

Ситуація перша: viewport ширший, ніж відео (aspect ratio екрана більший за 16:9). Відео розтягується по ширині на всю доступну область, але його висота стає більшою за висоту екрана, контент обрізається зверху і знизу. Область обрізки центрується автоматично.

Ситуація друга: viewport вужчий (aspect ratio менший за 16:9, наприклад, портретна орієнтація на планшеті). Відео розтягується по висоті на всю доступну область, ширина перевищує viewport, обрізається ліворуч і праворуч, центр зберігається.

object-fit: cover обробляє обидва сценарії сам. Але якщо ви з якихось причин працюєте без нього, наступний розділ для вас.

Класичний трюк із «великим контейнером»

До того як object-fit став стандартом, розробники використовували хитрий прийом. Суть: робимо контейнер свідомо більшим і за відео, і за viewport, а браузер сам центрує вміст.

Схема трюку з контейнером: пунктирний viewport, світле відео, темна oversize-область

На практиці це виглядає так:

1#myvid {
2 position: fixed;
3 top: 0;
4 left: 0;
5 width: 100%;
6 height: 100%;
7}
8
9@media (min-aspect-ratio: 16/9) {
10 #myvid {
11 height: 300%;
12 top: -100%;
13 }
14}
15
16@media (max-aspect-ratio: 16/9) {
17 #myvid {
18 width: 300%;
19 left: -100%;
20 }
21}

Медіазапити визначають, по якій осі пішло переповнення, і виставляють розмір, кратно більший за viewport, з від'ємним відступом для центрування. Відео виявляється в рази більшим за область перегляду, а браузер обрізає і центрує його стандартним механізмом заміщуваних елементів.

Сьогодні цей код, скоріше страховка для legacy-проєктів. Але якщо ви підтримуєте сайт, де object-fit з якоїсь причини недоступний, трюк працює безвідмовно.

Production-код: збираємо все разом

У реальному проєкті відео-тло рідко живе саме по собі. Поверх нього, заголовок, кнопка, форма, оверлей для читабельності тексту. Тому відео огортають у контейнер, який тримає розміри viewport:

1#SDStudio_VIDEO_BACKGROUND {
2 position: fixed;
3 top: 0;
4 right: 0;
5 bottom: 0;
6 left: 0;
7 overflow: hidden;
8}
9
10#SDStudio_VIDEO_BACKGROUND > video {
11 position: absolute;
12 top: 0;
13 left: 0;
14 width: 100%;
15 height: 100%;
16}
17
18/* Запасной вариант: если object-fit не поддерживается */
19@media (min-aspect-ratio: 16/9) {
20 #SDStudio_VIDEO_BACKGROUND > video {
21 height: 300%;
22 top: -100%;
23 }
24}
25
26@media (max-aspect-ratio: 16/9) {
27 #SDStudio_VIDEO_BACKGROUND > video {
28 width: 300%;
29 left: -100%;
30 }
31}
32
33/* Переопределяем, если object-fit доступен */
34@supports (object-fit: cover) {
35 #SDStudio_VIDEO_BACKGROUND > video {
36 top: 0;
37 left: 0;
38 width: 100%;
39 height: 100%;
40 object-fit: cover;
41 }
42}

Директива @supports перевіряє підтримку object-fit і перезаписує запасні правила. Сучасний браузер отримає чисте рішення з трьох рядків. Застарілий відпрацює через медіазапити і великий контейнер.

Розмітка при цьому мінімальна:

1<div id="SDStudio_VIDEO_BACKGROUND">
2 <video autoplay muted loop playsinline>
3 <source type="video/mp4" src="myvid.mp4"
4 media="(orientation: landscape)">
5 <source type="video/webm" src="myvid.webm"
6 media="(orientation: landscape)">
7 <source type="video/mp4" src="myvid_square.mp4"
8 media="(orientation: portrait)">
9 <source type="video/webm" src="myvid_square.webm"
10 media="(orientation: portrait)">
11 </video>
12</div>

Кілька деталей, які легко пропустити. muted обов'язковий: браузери блокують автовідтворення зі звуком. playsinline не дає iOS розгорнути відео на весь екран. Про loop нагадувати не потрібно, відео-тло без зациклення виглядає як помилка. І ще: надайте квадратне джерело для портретної орієнтації через media="(orientation: portrait)", стандартний 16:9 ролик на вертикальному екрані обріжеться майже повністю і перетвориться на безглузде миготіння.

⁉️🤔 Часті запитання

Чи обов'язково використовувати саме <video>, чи можна тлом поставити YouTube-ролик?

YouTube-iframe тлом ставити можна, але із застереженнями. Ви втрачаєте контроль над буферизацією, не можете прибрати елементи інтерфейсу, а мобільні браузери часто блокують автовідтворення iframe. Для тла саморобний <video> завжди кращий. Якщо вбудовуєте YouTube, додайте параметри ?autoplay=1&mute=1&controls=0&loop=1&playlist=VIDEO_ID.

Який формат відео обрати для максимальної сумісності?

Зв'язка MP4 (H.264) + WebM (VP8/VP9) покриває всі сучасні браузери. MP4, основний, WebM, для Chrome і Firefox (менший розмір за тієї самої якості). Роздільна здатність для тла: Full HD достатньо. Вище, приріст якості непомітний на тлі, а вага файлу зростає квадратично. Тримайте відео в межах кількох мегабайт для швидкого завантаження.

Що показувати користувачам, поки відео завантажується?

Ставте poster на <video>, статичний перший кадр або спеціально підготовлене зображення. CSS-фолбек: background-image на контейнері, який object-fit не перекриє (лежить шаром нижче). Мобільним користувачам на повільному з'єднанні відео-тло краще не завантажувати взагалі, медіазапит prefers-reduced-data і підміна на статичну картинку.

Як зробити текст поверх відео читабельним?

Додайте напівпрозорий оверлей між відео і контентом: background: rgba(0, 0, 0, 0.4) на псевдоелементі ::after контейнера з position: absolute; inset: 0; z-index: 1. Сам контент, з z-index: 2; position: relative. Коефіцієнт затемнення підбирайте під конкретне відео: світлому ролику потрібно більше, темному, менше.

Чи працює це на iOS і Android?

Так, із застереженнями. iOS вимагає playsinline (інакше відео йде в повноекранний плеєр). На iOS Safari версій до 10 object-fit не підтримується, спрацює запасний варіант із production-коду вище. Android Chrome відпрацьовує коректно. На обох платформах відео запускається тільки після першої взаємодії користувача, якщо не стоїть muted, тому muted суворо обов'язковий.

Що ставити у ваш проєкт: короткий вердикт

Якщо ви робите сайт у 2026 році, беріть object-fit: cover. Три рядки CSS, жодного JavaScript, повна адаптивність із коробки. Підтримка браузерами практично повсюдна, і кожного місяця охоплення тільки зростає.

Якщо у вас legacy з обов'язковою підтримкою старих Edge (до 79) або Firefox (до 36), production-код із розділу вище дасть вам обидва світи: @supports увімкне сучасне рішення, а медіазапити підхоплять решту.

І пам'ятайте: відео-тло — це вишенька на торті. Якщо ролик важить 20 мегабайт і завантажується вісім секунд, користувач піде раніше, ніж побачить ваш гарний заголовок. Стискайте, тестуйте на мобільній швидкості і завжди давайте статичний фолбек.

Чудового вам тла.