Responzivní web od nuly: mobile-first postup krok za krokem
Jak postavit web, který funguje na mobilu i monitoru: viewport, mobile-first CSS, fluidní typografie, obrázky se srcset a testování.
Responzivní web není „desktopová stránka, která se na mobilu nějak smrskne”. Je to stránka navržená tak, aby se přizpůsobila jakékoli šířce. Projdeme postup od prázdného HTML až po otestovaný výsledek.
1. Meta viewport – bez něj nic nefunguje
<meta name="viewport" content="width=device-width, initial-scale=1">
Bez tohoto řádku mobilní prohlížeč vykreslí stránku jako by měla šířku kolem 980 px a pak ji zmenší. Media queries pak nereagují tak, jak čekáte. Nepoužívejte user-scalable=no ani maximum-scale=1 – brání uživatelům v přiblížení a zhoršují přístupnost.
2. Rozumný základ CSS
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
}
img, video, svg {
max-width: 100%;
height: auto;
display: block;
}
box-sizing: border-box zajistí, že padding a border se započítávají do šířky – width: 100% pak opravdu znamená 100 %. Pravidlo pro obrázky zabrání nejčastějšímu důvodu horizontálního scrollování na mobilu.
3. Mobile-first: začněte nejužší obrazovkou
Výchozí styly píšete pro mobil a širší obrazovky přidáváte přes min-width:
.container {
padding-inline: 1rem;
}
.grid {
display: grid;
gap: 1rem;
}
@media (min-width: 640px) {
.grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1024px) {
.container {
max-width: 1100px;
margin-inline: auto;
}
.grid { grid-template-columns: repeat(3, 1fr); }
}
Proč takto? Mobilní layout je obvykle jednodušší (jeden sloupec), takže přidáváte složitost, místo abyste ji odebírali. CSS je kratší a méně se přepisuje.
Breakpointy nevolte podle konkrétních telefonů. Zúžte okno prohlížeče a breakpoint dejte tam, kde se design začne rozpadat.
4. Fluidní typografie s clamp()
Místo tří velikostí nadpisu pro tři breakpointy použijte plynulou škálu:
h1 {
font-size: clamp(1.75rem, 1.2rem + 2.5vw, 3rem);
}
clamp(min, preferovaná, max) – nadpis nebude menší než 1,75rem, větší než 3rem a mezi tím roste s šířkou okna. Do preferované hodnoty vždy přimíchejte rem, ne jen vw, jinak by text nereagoval na uživatelské zvětšení písma.
Pro délku řádku textu nastavte max-width: 65ch – řádky s 60–75 znaky se čtou nejpohodlněji.
5. Responzivní obrázky
Mobil nemusí stahovat obrázek pro 4K monitor:
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(min-width: 1024px) 50vw, 100vw"
width="1600" height="900"
alt="Tým při práci v kanceláři"
loading="lazy">
srcsetnabízí varianty s jejich šířkou v pixelech,sizesříká, jak široký bude obrázek na stránce,- prohlížeč si sám vybere nejmenší dostatečný soubor podle hustoty pixelů displeje.
Atributy width a height uveďte vždy – prohlížeč si podle nich rezervuje místo a stránka při načítání neposkakuje. loading="lazy" ale nedávejte na hlavní obrázek nahoře na stránce, ten má načíst co nejdřív.
Pokud potřebujete na mobilu úplně jiný výřez obrázku (art direction), použijte <picture> se <source media="...">.
6. Navigace na mobilu
Nejjednodušší funkční varianta bez JavaScriptu je <details>:
<nav>
<details class="menu">
<summary>Menu</summary>
<ul>
<li><a href="/">Domů</a></li>
<li><a href="/sluzby">Služby</a></li>
<li><a href="/kontakt">Kontakt</a></li>
</ul>
</details>
</nav>
Na širších obrazovkách pak menu zobrazíte trvale. Pokud stavíte vlastní hamburger tlačítko, nezapomeňte na <button> s aria-expanded a ovládání klávesnicí.
7. Dotykové cíle a hover
Tlačítka a odkazy by měly mít aspoň zhruba 44×44 px plochy. Efekty, které fungují jen na hover, schovejte za media query:
@media (hover: hover) {
.card:hover { transform: translateY(-2px); }
}
Na dotykovém zařízení by se jinak hover „zasekl” po klepnutí.
8. Container queries pro komponenty
Media queries reagují na šířku okna, ale komponenta karty může být jednou v úzkém sidebaru a jindy přes celou šířku. Container queries (podpora ve všech moderních prohlížečích) řeší právě tohle:
.card-wrap { container-type: inline-size; }
@container (min-width: 400px) {
.card { display: grid; grid-template-columns: 120px 1fr; }
}
9. Testování
- DevTools → Device Toolbar (Ctrl+Shift+M v Chrome) – rychlá kontrola různých šířek. Nezapomeňte zkusit i „divné” šířky jako 360 px a 820 px.
- Skutečný telefon – emulace nezachytí chování adresní lišty, klávesnice ani výkon.
- Horizontální scroll – v konzoli najdete viníka tímto snippetem:
document.querySelectorAll('*').forEach(el => {
if (el.offsetWidth > document.documentElement.clientWidth) console.log(el);
});
- Zvětšení písma na 200 % – layout se nesmí rozpadnout ani oříznout text.
Kontrolní seznam
- [ ] meta viewport bez blokování zoomu
- [ ]
box-sizing: border-boxamax-width: 100%pro média - [ ] styly mobile-first přes
min-width - [ ]
clamp()pro nadpisy,max-widthpro text - [ ]
srcset,sizes,widthaheightu obrázků - [ ] žádný horizontální scroll na 320 px
- [ ] otestováno na reálném zařízení