Martin Michálek Martin Michálek  – 18. 5. 2016

Na posledním firemním školení v Creoxu jsme otevřeli kodérský oříšek, který s dovolením sdílím, protože obsahuje hned tři zajímavosti.

Takhle vypadá zadání:

Úkol: Hlavička je na celou výšku okna, video na pozadí a centrované a na mobilech video není.

Postupně si to rozebereme, nebo si prostě prohlédněte hotové řešení.

Hlavička na celou výšku okna. Spodní část má fixní výšku

Tohle je to nejjednodušší. Tedy pokud znáte flexbox. ;)

HTML vypadá asi takto:

<div class="jumbo">
    <div class="jumbo-typo">
       <div class="jumbo-typo-main">    
           <!-- Nápis „I'm the masthead…“ -->
       </div>  
       <div class="jumbo-typo-bar">
          <!-- Lišta u spodní hrany: „Page content is below“ -->
       </div>    
    </div>
    <div class="jumbo-video">
        <!-- Video na pozadí -->
    </div>
</div>  

Na celou výšku okna (respektive viewportu) hlavičku roztáhneme pomocí nové jednotky vh:

.jumbo {
  height: 100vh;
}

Pojďme nejprve na část s obsahem – .jumbo-typo. Chceme, aby .jumbo-typo-bar zabral fixní výšku u spodní hrany a .jumbo-typo-main zbytek svislé plochy.

Nejprve z rodiče uděláme flexbox a změníme směr layoutu na zezhora dolů:

.jumbo-typo {
  display: flex;
  flex-direction: column;
}

Spodní lišta má výšku definovanou podle aktuálního obsahu a velikosti písma:

.jumbo-typo-bar {
  padding: 1em;
}  

Hlavní část zabere zbytek. Prostě jí přikážeme, ať flexí:

.jumbo-typo-main {
  flex: 1;
}

OK? Pojďme na video na pozadí.

Video je na pozadí a centrované vodorovně i svisle

Video nelze dát na pozadí do CSS a proto jej budeme pozicovat pod už hotovou typografickou částí .jumbo-typo. Nejprve na to musíme připravit rodiče. Vytvoříme z něj relativně pozicovaný kontejner a k tomu mu zakážeme zobrazovat vše co čouhá ven:

.jumbo {
  position: relative;
  overflow: hidden; 
}

Pro vycentrování videa a zároveň zachování jeho poměru stran si musíme pomoci méně známým, ale konzistentně fungujícím trikem. Je to takový background-size: cover pro video:

.jumbo-video {
  /* Video nesmí být menší než plocha, 
    kterou obývá: */
  min-width: 100%; 
  min-height: 100%;   
  /* Prohlížeči zakážeme video zmenšit 
    nebo zvětšit jen na jedné straně: */
  width: auto;
  height: auto;  
  /* Video vycentrujeme: */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);  
}

Na mobilních zařízeních video nahradíme obrázkem

Samozřejmě, že nás to může svádět k něčemu jako .jumbo-video { display: none; } na mobilních velikostech okna. To je ale samozřejmě špatně! Video se tak či tak stáhne, prohlížeč tatrankou neukecáte.

Daleko lepší je na to jít opačně – Mobile First cestou. Do stránky namísto videa vložíme obrázek:

<img 
 src="Wave-Sitting.jpg"
 data-videosrc="Wave-Sitting.mp4"
 alt="Wave Sitting"
 class="jumbo-video">

Ten pak Javascriptem zaměníme za značku <video>. Zjednodušeně třeba takto:

$('.jumbo-video').replaceWith('
  <video class="jumbo-video" autoplay loop preload>
    <source 
      src="'+$('.jumbo-video').attr('data-videosrc')+'" 
      type="video/mp4">
  </video>
');

Teď přemýšlejme nad podmínkou, pro kterou se Javascript spouští. Nabízí se použít Media Query. To by ale zase bylo špatně.

Musíme si odpovědět na otázku proč vlastně video na mobilech nechceme? Kromě nedostatku prostoru na obrazovce a zátěže pro rychlost načítání si musíme uvědomit, že v mobilní prohlížečích nefunguje vlastnost autoplay pro HTML5.

Takže můžeme výjimečně napsat funkci pro detekci podle user agent řetězce a pro video verzi všechny smartphony a tablety vyloučit:

if (!isMobile()) {
  $('.jumbo-video')
    .replaceWith(' /* … */ ');
}

Náhradní řešení pro prohlížeče co neumí flexbox

Chybí nám ještě alternativní verze IE9- a staré prohlížeče na Androidu, kde se vám layout kvůli použití flexboxu rozpadne. Ta bude velmi jednoduchá. Je důležité nechat zobrazit nerozbitý obsah. Veškeré stylování můžeme zahodit.

Využijeme detekci vlastnosti pomocí knihovny Modernizr a vytvoříme definovaný fallback:

.no-flexbox .jumbo {
  overflow: visible;
  position: static;
}

Podobně to provedeme i u dalších „nebezpečných vlastností“.

Prohlédněte si výslednou stránku, její kompletní zdroják. A do komentářů mně napište, pokud byste něco řešili jinak.