☰ menu
Pavel Satrapa

Responzivní design

Moderní stránky mění svou podobu v závislosti na rozměrech displeje či okna, ve kterém jsou prohlíženy. Na úzkém mobilu bývá vše uspořádáno do sloupce pod sebou, zatímco na širokých počítačových obrazovkách se prvky přesouvají vedle sebe, aby byl využit veškerý dostupný prostor. Toto přeuspořádání obsahu podle zobrazovače se nazývá responzivní design.

@media

Jeho základem jsou tak zvané mediální dotazy (media queries). Původně vznikly pro jiný účel – přizpůsobit podobu stránky podle média, na které je vykreslována. Jejich podoba je následující:

@media charakteristika média {
pravidla
}

Nejjednodušší charakteristikou média je jeho typ. Základní typy jsou screen pro obrazovky a print pro výstup na tiskárnu. Pravidla uvnitř mediálního dotazu platí, jen pokud médium splňuje charakteristiku. V opačném případě obsah @media jako kdyby v CSS vůbec nebyl.

Pravidla uvnitř @media nemají žádnou prioritu. Proto bývají mediální dotazy obvykle na konci CSS, aby při splnění podmínek přepsala pravidla před sebou.

Typickou aplikací mediálních dotazů je nastavení specifického vzhledu při tisku webové stránky. Například nechceme, aby se tisklo záhlaví, zápatí a navigační komponenty stránky. Také není vhodné, aby při tisku stránka končila bezprostředně pod nadpisem její části. Postaraly by se o to následující deklarace:

@media print {
    header,
    footer,
    nav {
        display: none;
    }

    h1, h2, h3, h4, h5, h6 {
        break-after: avoid;
    }
}

Rozměry

Tohle ovšem byla jen příprava. Charakteristika média může být složitější, což umožňuje slibovaný responzivní design. Můžete v ní logickou spojkou and kombinovat několik podmínek. K uplatnění pravidel uvnitř dojde, jen pokud budou všechny splněny.

Nejčastěji používané podmínky se týkají rozměrů okna prohlížeče (v originále viewport). Konkrétně min-width: X bude splněna, jen když je šířka okna alespoň X, zatímco max-width: Y požaduje, aby šířka okna byla nanejvýš Y. Existuje několik dalších (výška, orientace na výšku/na šířku), ale ve valné většině případů se pracuje se šířkou. Tyto podmínky jsou povonně uzavřeny do závorek.

Pro rozměry lze využívat různé jednotky. Populární jsou samozřejmě pixely, takže často uvidíte pravidla ve stylu:

@media screen and (min-width: 480px) {
    ...
}

Jelikož ale většinu obsahu stránek tvoří text, dává podle mne větší smysl využívat jednotky odvozené z něj. Zejména rem, což je výchozí velikost písma. Rozměr v rem v podstatě říká, kolik textu se vejde na řádek. Dávám proto přednost něčemu jako:

@media screen and (min-width: 40rem) {
    ...
}

Má-li mít rozložení stránky několik variant, můžete konstruovat složité podmínky typu od 25rem do 50rem:

@media screen and (min-width: 25rem) and (max-width: 50rem) {
    ...
}

V praxi se ale obvykle používá jednoduchý přístup se spodní mezí. Následuje další pravidlo pro širší okno, které přepíše vlastnosti svých předchůdců a de facto tak vytvoří jejich horní mez:

/* výchozí nastavení */

@media screen and (min-width: 25rem) {
    /* platí od 25rem */
}

@media screen and (min-width: 50rem) {
    /* platí od 50rem */
}

Podívejte se na příklad, kde se menu mění ze svislého pro úzké okno na vodorovné, pokud okno poskytuje dostatek místa. Zajišťují to deklarace:

li {
    display: block;
}

@media (min-width: 40rem) {
    li {
        display: inline-block;
    }
}

Plnohodnotný responzivní design bývá nejčastěji realizován pomocí mřížky, která podle šířky okna mění počet svých sloupců i rozmístění komponent stránky v nich. Praktickou ukázku můžete vidět na tomto příkladu.

Délkové jednotky

Při nastavování rozměrů, které mají reagovat na velikost okna prohlížeče, se může hodit několik speciálních jednotek, které byly pro tento účel navrženy:

Například následujícímu nadpisu jsem nastavil font-size: 3vw. Když budete měnit velikost okna prohlížeče, bude se odpovídajícím způsobem měnit i jeho velikost:

Velký text

Ukázka zároveň ilustruje jedno nebezpečí. Když dostatečně zúžíte okno, bude tento „velký text“ menší, než je základní velikost běžného textu. Pro tyto případy CSS nabízí funkci clamp(minimum,optimum,maximum). Dostane celkem 3 rozměry, které představují minimální, optimální a maximální rozměr. Pokud by výpočet optimálního rozměru překročil interval od minima po maximum, zastaví se vypočtená hodnota na jeho hranici.

Následující text má nastaveno font-size: clamp(1rem, 3vw, 2rem). Jeho velikost se tedy vypočte stejně jako v předchozí ukázce, ale nikdy neklesne pod 1rem a nezvětší se více než na 2rem:

Velký text