CSS/Styling

Z-index

Co je to z-index?

Z-index je CSS vlastnost, která určuje pořadí překrývání prvků na webové stránce ve třetím rozměru – na ose Z. Představte si webovou stránku jako vrstvu papírů na stole. Z-index rozhoduje, který papír leží navrchu a který je schovaný pod ním. Technicky řečeno, z-index kontroluje vrstvení pozicovaných elementů podél pomyslné osy, která směřuje směrem k vám od obrazovky. Čím vyšší hodnotu z-index má element, tím víc je "nahoře" a překrývá elementy s nižší hodnotou. Tato vlastnost je nepostradatelná při tvorbě moderních webů, kde často potřebujete zobrazit modální okna nad obsahem stránky, rozbalovací menu, které překrývá okolní prvky, nebo tooltip nápovědy nad textem. Z-index však funguje pouze u elementů s nastavenou CSS vlastností position na jinou hodnotu než static – tedy position: relative, absolute, fixed nebo sticky. Právě toto omezení je častým kamenem úrazu pro začátečníky, kteří přidají z-index, ale element se stále chová nepředvídatelně. Hodnota z-index může být kladné celé číslo, záporné celé číslo nebo hodnota auto. Výchozí hodnota je auto, což znamená, že element má stejnou vrstvu jako svůj rodič.

Jak z-index funguje v praxi?

Základní použití z-indexu je jednoduché. Pokud máte dva překrývající se elementy a chcete určit, který bude navrchu, přiřadíte vyšší z-index tomu, který má být viditelný. Například element s z-index: 10 bude překrývat element s z-index: 5. Důležité je si uvědomit, že z-index funguje pouze v rámci stejného stacking contextu, což je koncept, který vysvětlím níže. V praxi to znamená, že nemůžete jednoduše přiřadit obrovské číslo jako z-index: 999999 a očekávat, že element bude vždy navrchu všeho. Musíte porozumět hierarchii stacking contextů na vaší stránce.

Základní pravidla z-indexu

Platí pouze pro pozicované elementy. Element musí mít position: relative, absolute, fixed nebo sticky. Pokud má element výchozí position: static, z-index nemá žádný efekt. Vyšší hodnota = nahoře. Element s z-index: 100 překryje element s z-index: 1, pokud jsou ve stejném stacking contextu. Záporné hodnoty jsou možné. Můžete použít z-index: -1, což posune element pod elementy s z-index: auto nebo z-index: 0. To je užitečné, když chcete element schovat "za" normální obsah stránky. Čísla nemusí být po sobě jdoucí. Není rozdíl mezi z-index: 1 a 2 versus z-index: 100 a 200. Počítá se pouze relativní pořadí. Mnoho vývojářů používá mezery (10, 20, 30) pro snadnější budoucí vkládání nových vrstev.

Stacking context – klíčový koncept

Stacking context je izolovaná skupina elementů, která má vlastní hierarchii vrstvení. Je to jako samostatný balíček papírů, který můžete celý posunout výš nebo níž, ale pořadí papírů uvnitř balíčku zůstává stejné. Toto je nejdůležitější koncept pro pochopení toho, proč někdy z-index "nefunguje". Pokud máte element A s z-index: 1 a element B s z-index: 1000, ale element B je uvnitř jiného stacking contextu, který má nižší z-index než element A, pak element A bude stále navrchu. Rodičovský stacking context určuje pořadí pro všechny své děti jako celek.

Co vytváří nový stacking context?

  • Position a z-index

  • Element s position absolute, relative nebo fixed a z-index jiným než auto vytváří nový stacking context. To je nejběžnější způsob.

  • Opacity menší než 1

  • Element s opacity: 0.99 vytváří stacking context, i když nemá nastavený z-index. To často překvapí vývojáře.

  • Transform, filter, perspective

  • CSS vlastnosti jako transform: translateZ(0), filter: blur(5px) nebo perspective: 1000px také vytvářejí nový stacking context.

  • Position fixed nebo sticky

  • Elementy s position: fixed nebo position: sticky vždy vytvářejí nový stacking context, i bez explicitního z-indexu.

  • Flexbox a Grid děti se z-indexem

  • Když je rodič flex nebo grid container, jeho děti mohou používat z-index, i když nemají position jiné než static. Toto je výjimka z pravidla.

Praktické použití z-indexu

V reálném webovém vývoji se z-index používá v mnoha situacích. Pochopení správného použití vám ušetří hodiny debugování.

  • Modální okna a overlaye

  • Modální okno musí být nad vším ostatním obsahem. Běžně se používá vysoký z-index jako 1000 pro overlay pozadí a 1001 pro samotné okno. Overlay má většinou position: fixed a pokrývá celou obrazovku s poloprůhledným pozadím.

  • Sticky nebo fixed navigace

  • Navigace, která zůstává viditelná při scrollování, potřebuje z-index vyšší než obsah stránky, aby ho překrývala. Typicky z-index: 100 stačí, pokud nemáte jiné pevné elementy.

  • Dropdown menu

  • Rozbalovací menu musí překrývat obsah pod ním. Použijte position: absolute pro dropdown s vyšším z-indexem než okolní elementy. Dávejte pozor na stacking context hlavního menu.

  • Tooltips a popovery

  • Nápovědy zobrazené po najetí myší musí být nad všemi elementy v okolí. Použijte relativně vysoký z-index a ujistěte se, že nejsou omezené overflow: hidden na rodičovském elementu.

  • Překrývající se obrázky nebo karty

  • Design často vyžaduje dekorativní překrývání elementů. Použijte záporné marginy pro posunutí a z-index pro určení pořadí. Záporný z-index může posunout dekorativní element pod obsah.

Běžné chyby a jejich řešení

  • "Přidal jsem z-index 9999, ale stále to nefunguje!"

  • Problém je téměř vždy v tom, že element nemá nastavenou vlastnost position, nebo je v jiném stacking contextu. Řešení: Zkontrolujte, že element má position: relative, absolute, fixed nebo sticky. Prohlédněte si rodičovské elementy a zjistěte, jestli některý nevytváří nový stacking context, který omezuje váš element.

  • Element s vysokým z-indexem je pod elementem s nízkým z-indexem

  • To se stává, když rodičovský element s nízkým z-indexem vytváří stacking context. Jeho děti nikdy nemohou "vyskočit" nad jiný element mimo tento context, i s astronomickým z-indexem. Řešení: Přesuňte problematický element výše v DOM hierarchii, mimo omezující stacking context. Nebo zvyšte z-index rodičovského contextu.

  • Z-index nefunguje ve flexboxu nebo gridu

  • Toto vlastně není chyba – ve flexboxu a CSS gridu můžete používat z-index na dětech, i když nemají position. Ale stále potřebujete nastavit z-index explicitně. Řešení: Přidejte z-index přímo na flex nebo grid item, fungovat to bude bez position.

  • Používání náhodných vysokých čísel bez systému.

  • Když každý vývojář v týmu přidává "o trochu vyšší" z-index, skončíte s chaosem hodnot jako 999, 9999, 99999. Řešení: Vytvořte systém z-index vrstev. Například: 0-9 pro normální obsah, 10-99 pro dropdowny, 100-999 pro navigaci, 1000+ pro modální okna. Dokumentujte tento systém pro tým.

Z-index a přístupnost

Z-index ovlivňuje pouze vizuální pořadí elementů, ne pořadí v DOM ani pořadí při procházení tabulátorem. To může způsobit problémy s přístupností. Pokud uživatel s klávesnicí prochází stránku tabulátorem, focus může skákat mezi vizuálně vzdálenými elementy, které jsou v DOM blízko sebe. Vždy se ujistěte, že pořadí tabulátoru dává smysl, i když vizuální pořadí je změněné pomocí z-indexu. U modálních oken implementujte focus trap – zabraňte opuštění modálního okna tabulátorem, dokud není zavřené. Pro overlay pozadí použijte aria-hidden="true", aby čtečky obrazovky ignorovaly skrytý obsah pod modálním oknem.

Best practices pro používání z-indexu

Dlouhodobá udržovatelnost CSS kódu vyžaduje systematický přístup k z-indexu. Bez jasného systému snadno skončíte s chaosem náhodných hodnot.

  • Vytvořte si z-index škálu

  • Definujte si pevnou škálu hodnot pro různé typy elementů a držte se jí. Například: základní obsah 0-9, dropdowny 10-99, sticky navigace 100-199, tooltips 200-299, modální okna 1000-1999. Tuto škálu zdokumentujte a sdílejte s celým týmem. Můžete ji definovat jako CSS proměnné nebo v preprocesoru jako Sass.

  • Používejte CSS custom properties

  • Místo magických čísel rozsetých po celém CSS definujte z-index hodnoty jako proměnné. Například --z-index-dropdown: 50;, --z-index-modal: 1000;. Pak používejte z-index: var(--z-index-modal);. Pokud potřebujete změnit hierarchiu, upravíte jednu hodnotu na jednom místě.

  • Nepřehánějte to s vysokými hodnotami

  • Není důvod používat z-index: 999999;. Pokud potřebujete takovou hodnotu, máte pravděpodobně problém se stacking contextem, který byste měli vyřešit jinak. Držte hodnoty rozumné – většina projektů nepotřebuje z-index vyšší než 2000.

  • Minimalizujte počet stacking contextů

  • Každý nový stacking context přidává komplexitu. Vytvářejte je pouze když je to nutné. Dávejte pozor na vlastnosti, které nechtěně vytvářejí stacking context – opacity, transform, filter. Pokud element nefunguje s z-indexem jak očekáváte, zkontrolujte, jestli některý rodič nevytváří izolující context.

  • Testujte v různých kontextech

  • Element může vypadat správně v izolaci, ale selhat když je umístěn v reálném layoutu. Testujte komponenty s překrývajícími se elementy, uvnitř různých rodičů, s různými kombinacemi CSS vlastností. Zajistěte, že z-index funguje napříč celou aplikací.

Z-index v CSS frameworcích a knihovnách

Pokud používáte CSS framework jako Bootstrap, Tailwind CSS nebo Material-UI, mají již definovanou vlastní z-index škálu. Vždy si prostudujte dokumentaci frameworku, abyste věděli, jaké hodnoty používají pro své komponenty. Bootstrap například používá hodnoty od 1000 do 1060 pro dropdowny, sticky elementy, fixed navigaci, modály a tooltips. Pokud vytváříte vlastní komponenty, držte se jejich systému – nepoužívejte náhodné hodnoty, které mohou kolidovat s frameworkovými komponentami.

V Tailwind CSS můžete použít utility classes jako z-0, z-10, z-20z-50 pro běžné případy, nebo z-auto pro reset. Tailwind poskytuje i negativní hodnoty jako -z-10. Pokud potřebujete vlastní hodnotu mimo předefinovanou škálu, přidejte ji do konfigurace Tailwindu místo používání arbitrary values v každém místě.

Řešení pokročilých z-index scénářů

  • Dynamické modální okna nad sebou

  • Když uživatel může otevřít modální okno uvnitř modálního okna, potřebujete dynamicky zvyšovat z-index. Řešením je JavaScript, které sleduje otevřená okna a přiřazuje každému vyšší z-index. Alternativně můžete renderovat každé okno do separátního React portálu nebo Vue teleportu na nejvyšší úrovni DOM.

  • Tooltip nad modalem

  • Pokud tooltip uvnitř modálního okna má překrývat okraj modálu, musíte zajistit, že modal nevytváří izolující stacking context, nebo renderovat tooltip mimo modal (pomocí portálu). Moderní knihovny jako Floating UI nebo Popper.js to řeší automaticky.

  • Plná stránka overlay s výjimkou jednoho elementu

  • Když chcete ztmavit celou stránku kromě jednoho zvýrazněného elementu (například v onboarding průvodci), nemůžete použít prostý overlay s vysokým z-indexem. Řešením je buď použít mix-blend-mode, nebo renderovat overlay s výřezem pomocí SVG masky.

  • Animace mezi z-index vrstvami

  • Změna z-indexu během animace může způsobit blikání. Lepší je animovat opacity nebo transform a změnit z-index až na začátku nebo konci animace pomocí JavaScriptu. Alternativně můžete použít will-change: transform pro vytvoření stacking contextu předem.

Z-index v responzivním designu

Potřeby vrstvení se mohou lišit na různých velikostech obrazovky. Na desktopu může být navigace fixní s vysokým z-indexem, zatímco na mobilu může být součástí hamburger menu s nižším z-indexem. Používejte media queries k úpravě z-index hodnot podle potřeby. Například mobilní menu často potřebuje překrývat vše ostatní (z-index: 1000), zatímco na desktopu je menu součástí normálního flow a nepotřebuje z-index vůbec.

Responzivní design také ovlivňuje stacking context. Mobilní prohlížeče mohou renderovat fixed elementy jinak než desktopové prohlížeče. Testujte vrstvení na skutečných mobilních zařízeních, ne jen v DevTools simulátoru. Safari na iOS má specifické chování s position: fixed a z-indexem, které se může lišit od Chrome.

Nejčastější otázky o z-indexu

Proč z-index nefunguje na mém elementu? Rozbalit

Nejčastější důvod je, že váš element má výchozí position: static. Z-index funguje pouze na pozicovaných elementech – přidejte position: relative, absolute, fixed nebo sticky. Druhý častý důvod je stacking context – váš element může být omezen rodičovským stacking contextem s nižším z-indexem. V takovém případě žádné zvyšování z-indexu nepomůže, musíte vyřešit hierarchii contextů.

Jakou hodnotu z-indexu mám použít? Rozbalit

Neexistuje univerzální pravidlo, ale doporučuji vytvořit systém. Například: normální obsah 1-9, dropdowny a tooltips 10-99, sticky navigace 100-999, modální okna a overlaye 1000+. Nenechávejte mezery přiliš malé – z-index: 100, 200, 300 je lepší než 1, 2, 3, protože mezi nimi můžete v budoucnu vložit další vrstvy bez refactoringu. Vyhněte se extrémně vysokým hodnotám jako 999999 – není to nutné a signalizuje to špatné pochopení stacking contextu.

Co je to stacking context a proč je důležitý? Rozbalit

Stacking context je izolovaná skupina elementů s vlastní hierarchií vrstvení. Vytváří se například elementem s position a z-indexem, opacity menší než 1, nebo CSS transform. Důležitý je proto, že elementy uvnitř stacking contextu nemohou "vyskočit" nad elementy mimo něj, bez ohledu na jejich z-index. Rodičovský stacking context určuje pořadí pro všechny své děti jako celek. Proto nemůžete jen zvyšovat z-index donekonečna – musíte pochopit, ve kterém contextu váš element žije.

Můžu použít z-index bez position? Rozbalit

Většinou ne – z-index funguje pouze na pozicovaných elementech (position: relative, absolute, fixed, sticky). Existuje však výjimka: ve flexboxu a CSS gridu můžete použít z-index na potomcích (flex items nebo grid items), i když mají výchozí position: static. To je speciální chování těchto layout systémů. Pro běžné elementy mimo flex/grid musíte vždy přidat position.

Jak debugovat problémy se z-indexem? Rozbalit

Použijte DevTools v prohlížeči. Klikněte pravým tlačítkem na element a vyberte "Prozkoumat" (Inspect). V panelu Computed styles zkontrolujte, jaký má element skutečně nastaven position a z-index. Projděte rodičovské elementy a hledejte ty, které vytvářejí stacking context (opacity, transform, position s z-indexem). Pomocí dočasného nastavení výrazných barev pozadí (background) můžete vizualizovat pořadí překrývání. Zkuste vypnout z-index na rodičovských elementech a sledujte, jak se chování změní.