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% браузеров globally (данные 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 мегабайт и грузится восемь секунд, пользователь уйдёт раньше, чем увидит ваш красивый заголовок. Сжимайте, тестируйте на мобильной скорости и всегда давайте статичный фолбэк.

Отличного вам фона.