Responsivní design webu
Jak jednoduše a kvalitně vytvořit web, který se přizpůsobí všem velikostem cílových zařízení.
O různých možnostech, jak vytvořit stránku pro mobilní zařízení pojednává samostatný článek Jak na mobilní web. Tento text se věnuje tomu, jak s co nejmenší námahou vytvořit rozložení stránky (layout), který se bude vhodně přizpůsobovat různým velikostem viewportu (velikosti okna prohlížeče, kde se zobrazuje samotný obsah stránky, tj. bez záhlaví okna, stavového řádku a jiných lišt).
HTML je responsivní
První je dobré si uvědomit, že prosté HTML je v podstatě responsivní samo o sobě. Jde si to velmi jednoduše ověřit vypnutím CSS nebo zobrazením si hodně staré stránky z doby, kde se ještě CSS nepoužívalo.
Prakticky jediné, co je pro nová zařízení s menším displejem nutné udělat, je přidat jednu <meta> značku do hlavičky stránky (<head>
).
<meta name="viewport" content="width=device-width,initial-scale=1">
Tato značka zajistí, že prohlížeč zobrazí stránku v měřítku 1:1. Mobilní prohlížeče obvykle stránku bez tohoto <meta>
tagu zobrazí v jiném měřítku a přidají posuvník.
Zobrazení prostého HTML na mobilním zařízení s vhodnou podobou <meta name="viewport">
(ukázka):
Prostý text formátovaný základními HTML značkami, jako jsou nadpisy, odstavce nebo seznamy, se bude krásně přizpůsobovat prostoru viewportu.
A téže stránka bez této <meta>
značky (ukázka).
Po přidání jedné značky si tedy můžeme responsivitu webu dalšími úpravami už jen pokazit.
HTML výjimky
Existují určité případy, kdy se obsah HTML značky na stránku nevejde. To jsou například:
- obrázky (značka
<img>
), - videa, mapy a podobné objekty (většinou vloženy značkou
<iframe>
,<canvas>
,<svg>
) - tabulky (
<table>
), - zdrojové kódy (
<pre>
),
Musíme proto zajistit, aby nám svou větší šířkou nerozhodily layout.
Obrázky
Nejjednodušší způsob, jak omezit rozměry obrázku, je pomocí max-width: 100%
. Automatická výška (height: auto
) potom zajistí, že se výška dopočítá na základě šířky, takže nedojde ke změně poměru výšky a šířky, což by vedlo k deformaci (ukázka).
img {
max-width: 100%;
height: auto;
box-sizing: border-box
}
Chceme-li přímo obrázku přidat rámeček (border
) nebo odsazení (padding
), je dobré použí okrajový box-model (box-sizing: border-box
), aby se tyto hodnoty k šířce nepřičítaly.
Řešení to není úplně ideální, protože zmenšení rozměrů nezmenší datovou velikost.
Jak zajisit zmenšení rozměru obrázku a snížení jejich datové velikosti je popsáno v samostatném článku Responsivní obrázky.
Videa a objekty
Stejný postup jako u obrázků zajistí přizpůsobení se šířce i pro značky <iframe>
, <video>
, <svg>
nebo <canvas>
.
Do CSS pravidel minimální responsivní stránky si proto přidáme:
iframe, canvas, video, svg {
max-width: 100%;
box-sizing: border-box;
height: auto;
}
Jediný problém je správný poměr stran. U obrázku se poměr zachová, což třeba u <iframe>
neplatí. Často to vadit nemusí, ale někdy to vytváří nehezké situace.
Nejspolehlivější řešení by bylo výšku dopočítávat JavaScriptem, ale i v CSS jde využít triku dopočítávání výšky podle šířky. A připravit si tak několik obecných poměrů stran, které potom aplikujeme použitím příslušné CSS třídy.
.pomer-stran {
position: relative;
height: 0;
/* poměr stran 16:9 */
padding-top: 56.25%;
}
.pomer-stran > * {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
width: 100%; height: 100%;
}
HTML kód potom bude vypadat takto (dalším obalem můžeme nastavit maximální šířku):
<div style="max-width: 560px">
<div class="pomer-stran">
<iframe width="560" height="315" src=""></iframe>
</div>
</div>
Tabulky
Prosté řešení je tabulku obalit elementem s overflow-y: auto
.
.obal-tabulky {
overflow-y: auto;
}
Široká tabulka potom bude mít vodorovný posuvník, takže nerozhodí šířku celé stránky. Ukázka.
Pokročilejší postup je potom tabulku rozlámat.
A úplně nejlepší je dopředu myslet na to, že velké tabulky jsou na menších rozlišeních problematické, takže je pokud možné vytvářet jen s menším počtem sloupců / menší šířkou.
Zdrojové kódy
Zdrojový kód v <pre><code></pre></code>
jde rovněž obalit něčím s overflow: auto
jako tabulku. Existují ale, myslím, lepší řešení.
-
Nastavit
overflow: auto
přímo pro<pre>
:pre { overflow: auto; }
-
Povolit zalamování včetně rozlamování slov (při zkopírování bude kód v původním stavu):
pre { white-space: pre-wrap; word-wrap: break-word; }
Ukázka obou postupů (funkční od IE 8)
Celý příklad responsivního webu na GitHubu
Typografie
Délka řádků
Už máme docela hezky responsivní stránky, bohužel pro uživatele s velkým viewportem nebude čtení asi úplně příjemné. Na velkém monitoru a maximalisovaném okně prohlížeče můze vzniknou na jednom řádku cca 300 znaků.
To je poměrně dost a u delšího textu může být náročné po dočtení řádku správně trefit ten další. Proto oblast s textem omezíme maximální šířkou (max-width
).
Je samozřejmě nemožné stanovit nějakou přesnou hranici, kdy je řádek už moc dlouhý (zvlášť s ohledem na to, že schopnosti a podmínky návětšvníků webu jsou individuální).
Osobně vidím maximální hranici někde kolem 80 znaků, což může odpovídat cca šířce 35em
(záleží na velikosti písma a použitém fontu). Jelikož text se píše do odstavců, přidáme něco jako:
p {
max-width: 35em;
}
Velikost písma
Zadávat obecnou velikost není nutné, použije se ta, co má jako výchozí prohlížeč nebo uživatel. Případné zvětšování/zmenšování písma potom stačí provádět relativně, tj. například procenty, aby jednotlivé části stránky respektovaly nastavení prohlížeč/uživatele.
Výchozí velikost bývá často 16 pixelů. Ukázka z Firefoxu:
A Google Chrome:
Přidáme-li do kódu následující předpis:
h1 {
font-size: 300%;
}
Nadpis <h1>
bude mít trojnásobek (300 %) základní velikosti, tedy nejspíš 3 × 16 pixelů = 48 px. Ukázka.
Určovat velikost je dobré primárně pro hlavní obsah stránky a začít při nastavování písma právě tím. V případě, že je výchozí velikost pro použitý font příliš velká nebo malá, lehce ji upravíme pro <html>
nebo <body>
.
html {
font-size: 90%;
}
Potom přejdeme k nastavování dalších částí obsahu (nadpisy a podobně). Velikost písma se dědí, takže předchozí nadpis s 300% velikostí bude mít při globálním zmenšení písma pro <html>
ve finále velikost jen 90 % z té předchozí (48 pixelů), tedy přibližně 43 px (48 * 0.9). Ukázka.
Sloupcový layout
Fajn, web už je nyní krásně responsivní a dobře čitelný. Pokud je ale na stránce více obsahu, na velkých zobrazovacích zařízeních bude jen úzká dlouhá nudle a vedle ní hromada volného místa. Nabízí se proto obsah rozdělit do sloupců.
Pravidlo číslo jedna pro tvorbu vícesloupcového responsivního layoutu je nezadávat šířku v pixelech, ale ideálně v procentech.
Sloupce se vedle sebe potom dostanou obtékáním. Řekněme, že hlavní obsah bude mít 80 % šířky a postranní menu 20 %.
.obsah {
width: 80%;
float: left;
}
.menu {
width: 20%;
float: left;
}
Obtékání ukončí například obal
pomocí overflow: hidden
:
.obal {
overflow: hidden;
}
Pro případné přidávání rámečku nebo padding
u se hodí pro oba sloupce použít okrajový box-model (IE 8+) – nebude se o ně navyšovat šířka.
.obsah, .menu {
box-sizing: border-box;
}
Media queries
Nyní konečně do hry přichází CSS pravidlo @media
. Zmenšováním okna prohlížeče hledáme místo, kde už jsou dva sloupce moc a bylo by lepší je oba zobrazit pod sebou (analogicky to platí i pro vyšší počet sloupců).
Jak vhodnou šířku změřit? Po zapnutí vývojářských nástrojích v Chrome se při změně velikosti okna zobrazuje aktuální rozměr vpravo nahoře (je ale větší o šířku posuvníku).
Jinak je často šíři možné zjistit ze značky <html>
po jejím prozkoumání.
Nyní vytvoříme tzv. break-point, tedy místo, kde se aplikují odlišná pravidla (zruší se dvojsloupcovost layoutu, což jde třeba nastavením šířky na 100 % – dva elementy se 100% šířkou se vedle sebe nevejdou).
@media (max-width: 700px) {
.obsah, .menu {
width: 100%;
}
}
Ukázka (projeví se při změně velikosti okna kolem 700 px)
Jak je vidět, při zmenšení okna pod cca 700 px se menu přesune nad obsah. Pokud by bylo moc dlouhé, nabízí se ho schovat do tlačítka.
Výše uvedené @media
pravidlo se aplikuje vždy, když bude šířka pod 700 px. Chtěli-li bychom naopak něco aplikovat jen při šířce vyšší, použila by se vlastnost min-width
.
@media (min-width: 700px) {
/* Pravidla se aplikují při šířce 700 px a větší */
}
U používání pravidla @media
a zvlášť min-width
si je dobré uvědomit, že takto obalený kód nebude aplikován v IE 8 (nezná media queries). Jde-li proto o podporu IE 8, neměl by kód pro větší rozlišení (kde se typicky IE 8 používá) být obalen do @media
.
Rozměry media queries v pixelech
Někoho může zaskočit, že jsou v @media
pravidlu použity pixely, to samozřejmě není ideální a bylo by vhodné je přepočítat na relativní jednotky. Proč? Při odlišné velikosti písma nebudou absolutní hodnoty break-pointů v px sedět pro větší písmo.
Obrázek ilustruje, jak při zvětšení písma ze strany uživatele u předchozí ukázky bude break-point v pixelech totálně mimo. Šířka menu je při větším písmu nedostatečná a přeskládání pod sebe by mělo nastat dříve. V tomto případě to není tak strašné, ale často to může významně rozhodit layout nebo způsobit nečitelnost některých částí stránky, když je překryje něco, co nemá.
Takto třeba vypadá hlavní stránka Seznamu při hraniční šířce a zvětšeném písmu:
Chceme-li nastavit hodnotu hraničních bodů v např. em
místo v px
, potřebujeme zjistit kolik pixelů má jeden em
. To jde buď prozkoumáním základní velikosti písma v nastavení prohlížeče, nebo třeba tak, že na čisté stránce pro <body>
nastavíme font-size: 1em
a něco do něj napíšeme. A ve vypočítaných stylech <body>
se potom ukáže velikost písma v pixelech (v tomto případě 16 px).
Teď jen stačí provést jednoduchý výpočet 700 / 16
a vyjde odpovídající hodnota v em
.
Kalkulačka pixelů na em
Ukázka předchozího dvou-sloupcového layoutu s převedenými break-pointy do em
rozměrů.
Při srovnatelné šířce, bude už dávno menu a obsah pod sebou.
Omezení šířky layoutu
Kvůli maximálnímu počtu znaků na řádek byla nastavena max-width
pro odstavec (<p>
). Když se ale podíváme na poslední podobu příkladu responsivního layoutu na větším monitoru, vidíme pořád spoustu nevyužitého prostoru.
Možná by bylo hezčí omezit šířku celého layoutu a třeba to ještě celé horisontálně vycentrovat.
.obal {
max-width: 65em; /* maximální šířka */
margin: auto; /* vodorovné vycentrování */
}
Odkazy jinam
- CSS-tricks.com: Testování počtu znaků mez 45–75 znaky
- SmashingMagazine: Úprava velikosti písma a výšky řádků
- Sitepoint: Kdy používat vertikální media-queries
- Fluidity: Důkaz, že je HTML responsivní samo o sobě
- Tuts+ Web Design: A “Readability First” Approach to Media Queries and Layout
Komentáře