Efektowne wideo w tle sekcji hero to dziś standard w projektach dla instytucji, uczelni czy nowoczesnych marek. Problem w tym, że najprostsza implementacja – czyli włączenie wideo z poziomu ustawień Divi (i większości innych wizualnych narzędzi do budowania stron) – w praktyce łamie kilka wymagań WCAG 2.1 na poziomie AA. Dla firmy czy NGO, które podlegają Ustawie o dostępności cyfrowej lub Europejskiemu Aktowi o Dostępności (EAA), to nie jest kwestia estetyki, tylko realne ryzyko prawne.
W tym wpisie pokazuję, jak wygląda to zagadnienie od strony wykonawczej – na przykładzie autorskiego modułu Hero Video, który wdrażam u swoich klientów zamiast natywnego mechanizmu tła wideo w Divi.
Dlaczego natywne wideo w tle w Divi jest problemem
Standardowy mechanizm tła wideo w Divi ma trzy słabe punkty, które dotykają zarówno wydajności, jak i dostępności:
- Brak realnej kontroli nad autoodtwarzaniem. WCAG 2.2.2 (Pause, Stop, Hide) wymaga, aby ruchoma, autoodtwarzana treść trwająca dłużej niż 5 sekund dała się zatrzymać przez użytkownika. Domyślny moduł Divi takiej kontrolki nie ma.
- Ignorowanie preferencji systemowych. Część użytkowników – np. osoby z migreną, epilepsją światłoczułą czy zaburzeniami przedsionkowymi – włącza w systemie opcję „ogranicz ruch” (prefers-reduced-motion). Natywny mechanizm Divi tej preferencji nie odczytuje.
- Wydajność i fallback. Domyślne tło wideo dokłada narzut skryptów Divi i słabo radzi sobie z obrazem zastępczym na wolniejszych łączach, co odbija się też na Core Web Vitals, a więc pośrednio na SEO.
Do tego dochodzi kwestia formalna: strony podmiotów publicznych i organizacji pozarządowych realizujących zadania publiczne podlegają w Polsce Ustawie o dostępności cyfrowej stron internetowych i aplikacji mobilnych (wdrażającej unijną dyrektywę 2016/2102) już od kilku lat. Firmy prywatne oferujące usługi konsumenckie online – w tym sklepy i wiele usług cyfrowych – od 28 czerwca 2025 r. podlegają dodatkowo <cite index=”4-1″>Europejskiemu Aktowi o Dostępności, którego polska implementacja wymaga zgodności z WCAG 2.1 na poziomie AA</cite>. Mikroprzedsiębiorstwa (poniżej 10 osób i 2 mln euro obrotu) mają pewne zwolnienia, ale <cite index=”5-1″>to nie oznacza, że ich strona może być całkowicie niedostępna</cite> – a instytucje i NGO zwykle w ogóle nie łapią się na ten wyjątek.
Innymi słowy: jeśli robisz stronę dla instytucji, uczelni, fundacji albo świadomej firmy, wideo w tle „na domyślnych ustawieniach Divi” to gotowy powód do skargi lub uwagi w audycie dostępności.
Rozwiązanie: autorski moduł Hero Video zamiast natywnego tła
Zamiast polegać na wbudowanym mechanizmie, buduję sekcję hero od zera – czystym HTML, CSS i JavaScriptem, osadzonym w Divi jako Moduł Kodu. Takie podejście daje pełną kontrolę nad trzema rzeczami, których natywny Divi nie oferuje:
- Przyciskiem play/pause widocznym cały czas, z poprawnymi atrybutami
aria-labeliaria-pressed, które aktualizują się dynamicznie wraz ze stanem odtwarzacza. - Automatycznym wykrywaniem
prefers-reduced-motion– jeśli użytkownik ma w systemie włączoną redukcję ruchu, wideo w ogóle się nie odtwarza, a widoczny jest bezpieczny obraz zastępczy. - Blokadą Picture-in-Picture i brakiem dźwięku – wideo jest zawsze wyciszone (
muted), więc nie narusza WCAG 1.4.2 (Audio Control), a dodatkowa blokada PiP (CSS + JS) eliminuje niepożądane, pływające okienko wideo, które potrafi rozwalić layout na urządzeniach mobilnych.
Do tego dochodzi warstwa czysto techniczna: obraz poster i tag <img> jako fallback ładują się błyskawicznie, a atrybut preload="auto" sprawia, że przeglądarka priorytetyzuje pobieranie wideo bez narzutu skryptów page buildera.
Demo – zobacz działanie w praktyce
Poniżej uproszczone demo pokazujące dokładnie ten mechanizm: przycisk zatrzymuje animację w tle, a etykieta i aria-pressed zmieniają się razem ze stanem odtwarzacza. W finalnej wersji tło stanowi realne wideo klienta – tutaj, żeby demo działało od razu w artykule bez dodatkowych plików, zastąpiłam wideo animowanym gradientem obrazującym ten sam mechanizm sterowania.
Kliknij przycisk, żeby zobaczyć zachowanie zgodne z WCAG 2.2.2 – animacja zatrzymuje się, pokazuje się fallback, a aria-pressed i etykieta się aktualizują.
Gotowy kod do wklejenia w Moduł Kodu Divi
<!-- ========================================== -->
<!-- 1. STRUKTURA HTML -->
<!-- ========================================== -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<div id="premium-hero-wrapper">
<!-- OBRAZ FALLBACK -->
<img id="hero-fallback-img"
src="TUTAJ_WKLEJ_LINK_DO_OBRAZU_FALLBACK.jpg"
alt="Tło sekcji przedstawiające [wpisz dokładny opis]" />
<!-- WIDEO PREMIUM -->
<video id="hero-premium-video"
autoplay muted playsinline disablepictureinpicture
preload="auto"
poster="TUTAJ_WKLEJ_LINK_DO_OBRAZU_FALLBACK.jpg"
aria-label="Krótkie wideo w tle pokazujące [wpisz opis]">
<source src="TUTAJ_WKLEJ_LINK_DO_WIDEO.mp4" type="video/mp4">
Twoja przeglądarka nie obsługuje odtwarzacza wideo.
</video>
<!-- PRZYCISK STERUJĄCY -->
<div id="hero-controls-container">
<button id="bg-video-toggle" class="bg-video-toggle" aria-label="Zatrzymaj animację w tle" aria-pressed="false">
<i class="fa-solid fa-pause" aria-hidden="true"></i>
<span class="label">Zatrzymaj tło</span>
</button>
</div>
</div>
<!-- ========================================== -->
<!-- 2. STYLE CSS -->
<!-- ========================================== -->
<style>
#premium-hero-wrapper {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 100vw;
height: 100%;
min-height: 65vh;
background-color: #1a1a1a;
overflow: hidden;
z-index: 0;
}
#hero-fallback-img {
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
object-fit: cover; z-index: 1;
}
#hero-premium-video {
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
object-fit: cover; z-index: 2;
opacity: 1;
transition: opacity 0.6s ease-in-out;
pointer-events: none; /* blokada interakcji myszy, np. ikony PiP */
}
#hero-premium-video.is-hidden { opacity: 0; }
#hero-controls-container {
position: absolute; bottom: 30px; right: 30px; z-index: 9999;
}
.bg-video-toggle {
background: rgba(0, 0, 0, 0.65);
color: #fff;
padding: 12px 18px;
border-radius: 8px;
font-size: 17px;
border: 2px solid #fff;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 10px;
transition: all 0.3s ease;
}
.bg-video-toggle:focus-visible {
outline: 3px solid #c29c43;
outline-offset: 4px;
}
.bg-video-toggle:hover { background: rgba(0, 0, 0, 0.85); }
@media (max-width: 980px) {
#premium-hero-wrapper { min-height: 50vh; }
#hero-controls-container { bottom: 25px; right: 25px; }
}
@media (max-width: 767px) {
#premium-hero-wrapper { min-height: 40vh; }
.bg-video-toggle .label { display: none; }
#hero-controls-container { bottom: 20px; right: 20px; }
}
</style>
<!-- ========================================== -->
<!-- 3. SKRYPT JAVASCRIPT -->
<!-- ========================================== -->
<script>
document.addEventListener("DOMContentLoaded", function () {
const video = document.getElementById('hero-premium-video');
const toggleBtn = document.getElementById('bg-video-toggle');
const icon = toggleBtn.querySelector('i');
const label = toggleBtn.querySelector('.label');
function pauseVideoAndShowFallback() {
video.pause();
video.classList.add('is-hidden');
icon.classList.remove('fa-pause');
icon.classList.add('fa-play');
label.textContent = "Odtwórz tło";
toggleBtn.setAttribute('aria-label', "Odtwórz animację w tle");
toggleBtn.setAttribute('aria-pressed', "true");
}
function playVideo() {
video.play();
video.classList.remove('is-hidden');
icon.classList.remove('fa-play');
icon.classList.add('fa-pause');
label.textContent = "Zatrzymaj tło";
toggleBtn.setAttribute('aria-label', "Zatrzymaj animację w tle");
toggleBtn.setAttribute('aria-pressed', "false");
}
if (video && toggleBtn) {
video.disablePictureInPicture = true;
video.setAttribute('controlsList', 'nodownload noplaybackrate nofullscreen');
toggleBtn.addEventListener('click', function () {
if (video.paused) { playVideo(); } else { pauseVideoAndShowFallback(); }
});
video.addEventListener('ended', pauseVideoAndShowFallback);
// A11Y: redukcja ruchu
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
if (prefersReducedMotion.matches) { pauseVideoAndShowFallback(); }
// Zabezpieczenie przed błędem autoplay
let playPromise = video.play();
if (playPromise !== undefined) {
playPromise.catch(() => { pauseVideoAndShowFallback(); });
}
}
});
</script>
Jak to wdrożyć w Divi krok po kroku
- Sekcja. Nowa sekcja bez tła (zdjęcia, wideo, kolorów), marginesy i paddingi górny/dolny na
0px, w zakładce Zaawansowane → Pozycja ustawWzględna. - Moduł Kodu. Wstaw Moduł Kodu do sekcji, w Zaawansowane → Pozycja ustaw
Absolutna, zakotwicz w lewym górnym rogu,z-index: 0. Wklej cały kod powyżej. - Podmiana danych. Zamień
TUTAJ_WKLEJ_LINK_DO_OBRAZU_FALLBACK.jpg(2 wystąpienia) iTUTAJ_WKLEJ_LINK_DO_WIDEO.mp4(1 wystąpienie) na realne adresy z biblioteki mediów. Uzupełnijaltiaria-labelkonkretnym opisem tego, co dzieje się na wideo. - Wysokość sekcji. W Ustawieniach Sekcji → Projekt → Rozmiary → Min. wysokość ustaw wartości responsywne: 65vh (pulpit), 50vh (tablet), 40vh (telefon) – zgodnie z CSS w module.
Checklista dostępności do tego typu sekcji
- Wideo jest wyciszone (
muted) – brak autoodtwarzania dźwięku (WCAG 1.4.2). - Widoczny przycisk zatrzymania animacji trwającej dłużej niż 5 s (WCAG 2.2.2).
- Skrypt reaguje na
prefers-reduced-motioni domyślnie zatrzymuje wideo dla osób, które włączyły tę preferencję w systemie. - Przycisk ma poprawny kontrast i widoczny obrys przy nawigacji klawiaturą (
:focus-visible). aria-labeliaria-pressedprzycisku aktualizują się razem ze stanem odtwarzacza.- Obraz fallback ma sensowny, opisowy atrybut
alt. - Wideo nie zawiera efektów migotania ani szybkich błysków (WCAG 2.3.1).
Dlaczego to się opłaca nie tylko instytucjom
Publiczne strony i te realizujące zadania publiczne od dawna muszą spełniać krajową ustawę o dostępności cyfrowej. Firmy prywatne i NGO prowadzące sprzedaż lub usługi online dołączyły do tego obowiązku wraz z wejściem w życie EAA 28 czerwca 2025 r., kiedy wszystkie nowo oferowane produkty i usługi cyfrowe muszą już spełniać wymogi dostępności. Dla stron istniejących wcześniej przewidziano okres przejściowy, ale nowo wdrażane treści i funkcje – takie jak świeżo dodana sekcja hero – powinny być zgodne od razu.
Niezależnie od tego, czy dany podmiot formalnie podlega pod EAA, dostępna sekcja hero to też: lepszy wynik Core Web Vitals (bo rezygnujemy z ciężkiego mechanizmu Divi), mniej reklamacji od użytkowników z czytnikami ekranu i realny argument sprzedażowy, gdy klient pyta „czy to będzie zgodne z WCAG?”.
FAQ
Jeśli wideo pełni czysto dekoracyjną rolę i nie zawiera treści informacyjnej ani ścieżki dźwiękowej, napisy nie są wymagane – kluczowe jest jednak wyciszenie i możliwość zatrzymania animacji.
muted, żeby spełnić WCAG? Nie. Sam brak dźwięku nie zwalnia z obowiązku dania użytkownikowi kontroli nad ruchomą treścią (WCAG 2.2.2) ani z uwzględnienia preferencji prefers-reduced-motion.
Częściowo – da się dodać przycisk pauzy nakładką CSS, ale bez własnego skryptu nie ma kontroli nad prefers-reduced-motion, blokadą PiP ani realnym priorytetem ładowania pliku.
Podmiotów publicznych i realizujących zadania publiczne – od lat, na mocy ustawy z 2019 r. Od 28 czerwca 2025 r. dołączyły do nich firmy prywatne oferujące określone usługi i produkty konsumenckie online, na mocy Europejskiego Aktu o Dostępności, z pewnymi wyłączeniami dla mikroprzedsiębiorstw.
Potrzebujesz wdrożyć taką sekcję u siebie albo sprawdzić, czy Twoja strona spełnia wymogi WCAG? Napisz do mnie i umów konsultację – przygotuję audyt i wdrożę rozwiązanie dopasowane do Twojej instytucji.
