
🎬 Adaptacyjne tło wideo w CSS: pełny poradnik z przykładami kodu
Wchodzą Państwo na stronę i pierwszą rzeczą, którą widzą, nie jest statyczny obrazek, a żywe wideo na cały ekran, które oddycha. Wygląda drogo. Wygląda profesjonalnie. I co najważniejsze, działa na każdym urządzeniu, od telefonu po ultraszeroki monitor, bez ani jednego czarnego paska.
Wydaje się, że do tego potrzebny jest JavaScript, mierzenie viewportu i skomplikowana matematyka. Też tak myślałem, kiedy pierwszy raz zabrałem się za to zadanie. Próbowałem calc(), jednostek viewport, pisałem nawet skrypt pod resize, w Firefoksie działało, w Chrome się rozjeżdżało, w Safari w ogóle milczało.
A potem okazało się, że w CSS już od kilku lat istnieje właściwość, która robi dokładnie to, czego potrzebujemy, bez ani jednej linijki JS. I dziś pokażę, jak zbudować w pełni responsywne tło wideo, które zachowuje się jak background-size: cover, ale dla żywego wideo.
💡 Szybki przegląd:
- Ustawiamy element wideo na stałe pozycjonowanie na cały viewport
- Stosujemy object-fit cover, wideo samo się dopasowuje, przycinając nadmiar i zachowując środek
- Dla starszych przeglądarek trzymamy wariant zapasowy na media queries i „dużym kontenerze"
- Opakowujemy wszystko w kontener, przyda się do overlayu, przycisków i tekstu na wideo
- Dostosowujemy pod urządzenia mobilne: inne źródło, playsinline i obrazek zastępczy
Podstawowe podejście: stałe pozycjonowanie
Każde tło wideo zaczyna się od tego, że <video> zajmuje cały obszar widoku. Robi się to przez position: fixed z zerowymi odstępami:
1 #myvid { 2 position: fixed; 3 top: 0; 4 right: 0; 5 bottom: 0; 6 left: 0; 7 }
Element rozciąga się dokładnie na szerokość i wysokość viewportu. Problem pojawia się natychmiast: wideo prawie zawsze jest nagrane w proporcjach 16:9, a ekran użytkownika może być kwadratowy, ultraszeroki lub portretowy. Rezultat to te same czarne pasy, które zabijają cały efekt.

Jeśli pracowali Państwo z obrazami tła w CSS, to wiedzą Państwo: w background-size istnieje wartość cover. Sprawia ona, że obrazek wypełnia kontener w całości, przycinając nadmiar i zachowując proporcje. Dokładnie takiego samego zachowania potrzeba od wideo. I ono istnieje.
Nowoczesne rozwiązanie: object-fit: cover
Właściwość object-fit jest stworzona właśnie do tego. Określa ona, jak element zastępowany (obraz lub wideo) wpasowuje się w swój kontener, a wartość cover działa dokładnie jak 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 }
Wideo jest skalowane tak, aby całkowicie wypełnić kontener. Jeśli proporcje się nie zgadzają, przeglądarka przycina nadmiar z góry i z dołu (lub z lewej i prawej) i automatycznie centruje rezultat. Żadnych czarnych pasów.
Na rok 2026 object-fit wspiera 96,39% przeglądarek globalnie (dane Can I Use). Chrome od wersji 32, Firefox od 36, Safari od 10, Edge od 79. Internet Explorer 11 nie wspiera, ale jego udział rynkowy zmierza do zera, a okres wsparcia minął.
Dla zdecydowanej większości projektów te trzy linijki CSS są wystarczające. Tło wideo jest gotowe.
Problemy ze skalowaniem: co się dzieje „pod maską"
Nawet jeśli używają Państwo object-fit, warto rozumieć mechanikę. Możliwe są dwa scenariusze:

Sytuacja pierwsza: viewport jest szerszy niż wideo (aspect ratio ekranu większy niż 16:9). Wideo rozciąga się na szerokość na cały dostępny obszar, ale jego wysokość staje się większa niż wysokość ekranu, zawartość jest przycinana z góry i z dołu. Obszar przycięcia jest centrowany automatycznie.
Sytuacja druga: viewport jest węższy (aspect ratio mniejszy niż 16:9, na przykład orientacja portretowa na tablecie). Wideo rozciąga się na wysokość na cały dostępny obszar, szerokość przekracza viewport, jest przycinane z lewej i prawej, środek jest zachowany.
object-fit: cover obsługuje oba scenariusze samodzielnie. Ale jeśli z jakichś powodów pracują Państwo bez niego, następny rozdział jest dla Państwa.
Klasyczny trik z „dużym kontenerem"
Zanim object-fit stał się standardem, deweloperzy używali sprytnego chwytu. Sedno: robimy kontener celowo większy i od wideo, i od viewportu, a przeglądarka sama centruje zawartość.

W praktyce wygląda to tak:
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 }
Media queries określają, na której osi nastąpiło przepełnienie, i ustawiają rozmiar wielokrotnie większy od viewportu, z ujemnym marginesem do centrowania. Wideo okazuje się wielokrotnie większe od obszaru widoku, a przeglądarka przycina je i centruje standardowym mechanizmem elementów zastępowanych.
Dziś ten kod to raczej zabezpieczenie dla projektów legacy. Ale jeśli wspierają Państwo stronę, gdzie object-fit z jakiegoś powodu jest niedostępny, trik działa niezawodnie.
Kod produkcyjny: składamy wszystko razem
W rzeczywistym projekcie tło wideo rzadko żyje samo dla siebie. Na nim znajduje się nagłówek, przycisk, formularz, overlay dla czytelności tekstu. Dlatego wideo opakowuje się w kontener, który trzyma rozmiary viewportu:
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 }
Dyrektywa @supports sprawdza wsparcie dla object-fit i nadpisuje reguły zapasowe. Nowoczesna przeglądarka otrzyma czyste rozwiązanie z trzech linijek. Przestarzała obsłuży to przez media queries i duży kontener.
Znacznik przy tym jest minimalny:
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>
Kilka szczegółów, które łatwo przeoczyć. muted jest obowiązkowe: przeglądarki blokują autoodtwarzanie z dźwiękiem. playsinline nie pozwala iOS rozwinąć wideo na cały ekran. O loop nie trzeba przypominać, tło wideo bez zapętlenia wygląda jak błąd. I jeszcze: proszę dostarczyć kwadratowe źródło dla orientacji portretowej przez media="(orientation: portrait)", standardowy klip 16:9 na pionowym ekranie zostanie przycięty prawie całkowicie i zamieni się w bezsensowne migotanie.
⁉️🤔 Często zadawane pytania
Czy koniecznie trzeba używać właśnie <video>, czy można jako tło ustawić film z YouTube?
YouTube-iframe jako tło można ustawić, ale z zastrzeżeniami. Tracą Państwo kontrolę nad buforowaniem, nie mogą usunąć elementów interfejsu, a przeglądarki mobilne często blokują autoodtwarzanie iframe. Dla tła własny
<video>jest zawsze lepszy. Jeśli osadzają Państwo YouTube, proszę dodać parametry?autoplay=1&mute=1&controls=0&loop=1&playlist=VIDEO_ID.
Jaki format wideo wybrać dla maksymalnej kompatybilności?
Zestaw MP4 (H.264) + WebM (VP8/VP9) pokrywa wszystkie nowoczesne przeglądarki. MP4 jako główny, WebM dla Chrome i Firefox (mniejszy rozmiar przy tej samej jakości). Rozdzielczość dla tła: Full HD jest wystarczające. Wyżej przyrost jakości jest niezauważalny na tle, a waga pliku rośnie kwadratowo. Proszę trzymać wideo w granicach kilku megabajtów dla szybkiego ładowania.
Co pokazywać użytkownikom, gdy wideo się ładuje?
Proszę ustawić
posterna<video>, statyczną pierwszą klatkę lub specjalnie przygotowany obraz. CSS-fallback:background-imagena kontenerze, któregoobject-fitnie przykryje (leży warstwą niżej). Użytkownikom mobilnym na wolnym połączeniu lepiej w ogóle nie ładować tła wideo, media queryprefers-reduced-datai podmiana na statyczny obrazek.
Jak sprawić, by tekst na wideo był czytelny?
Proszę dodać półprzezroczysty overlay między wideo a treścią:
background: rgba(0, 0, 0, 0.4)na pseudoelemencie::afterkontenera zposition: absolute; inset: 0; z-index: 1. Sama treść zz-index: 2; position: relative. Współczynnik przyciemnienia proszę dobrać pod konkretne wideo: jasny klip potrzebuje więcej, ciemny mniej.
Czy to działa na iOS i Androidzie?
Tak, z zastrzeżeniami. iOS wymaga
playsinline(w przeciwnym razie wideo przechodzi w pełnoekranowy odtwarzacz). Na iOS Safari w wersjach przed 10object-fitnie jest wspierany, zadziała wariant zapasowy z kodu produkcyjnego powyżej. Android Chrome działa poprawnie. Na obu platformach wideo uruchamia się tylko po pierwszej interakcji użytkownika, jeśli nie ma ustawionegomuted, dlategomutedjest bezwzględnie obowiązkowe.
Co zastosować w Państwa projekcie: krótki werdykt
Jeśli robią Państwo stronę w 2026 roku, proszę brać object-fit: cover. Trzy linijki CSS, zero JavaScriptu, pełna responsywność od razu po wyjęciu z pudełka. Wsparcie przeglądarek jest praktycznie powszechne i z każdym miesiącem zasięg tylko rośnie.
Jeśli mają Państwo legacy z obowiązkowym wsparciem starych Edge (przed 79) lub Firefox (przed 36), kod produkcyjny z rozdziału powyżej da Państwu oba światy: @supports włączy nowoczesne rozwiązanie, a media queries obsłużą resztę.
I proszę pamiętać: tło wideo to wisienka na torcie. Jeśli klip waży 20 megabajtów i ładuje się osiem sekund, użytkownik odejdzie, zanim zobaczy Państwa piękny nagłówek. Proszę kompresować, testować na mobilnej prędkości i zawsze dawać statyczny fallback.
Wspaniałego tła dla Państwa.



