Zarovnávání bloků s CSS

Pavel Salvet  /  28. 11. 2008, 12:08

Posouvání různých boxů sem a tam není někdy vůbec snadnou záležitostí a bez základních znalostí a zkušeností to může trvat hodiny vyčerpávajícího úsilí, než se dospěje ke kýženému výsledku. Zejména vertikální centrování je těžký oříšek. Snad následující pojednání někomu trochu času ušetří.

Zarovnávání bloků se děje prostřednictvím vlastnosti margin. Internet Explorer, renderuje-li stránku v režimu zpětné kompatibility, dokáže bloky horizontálně zarovnávat, v souladu s překonanou specifikací CSS 1, pomocí vlastnosti text-align. To je však především na překážku, protože hodnota vlastnosti text-align se dědí z rodičovského prvku na jeho potomky, takže obsah rodičovského prvku se pak kvůli tomu musí většinou explicitně zarovnat do původní strany, což je zbytečná práce navíc.

Normálně se blokové prvky zarovnávají nahoru a doleva. Jak to tedy změnit? Jednoduše tím, že se nastaví rozměry vnějších okrajů bloku.
 

Příklady zarovnávání bloků
Deklarace Interpretace
margin-left:0 blok bude zleva odsazen o 0 px, tedy zarovnán doleva
margin-right:0 blok bude zprava odsazen o 0 px, tedy zarovnán doprava
margin-top:0 blok bude vzdálený 0 px od okraje předchozího bloku
margin-bottom:0 blok bude vzdálený 0 px od okraje následujícího bloku
margin:0 kombinace všech předešlých deklarací
margin: auto okraje bloku se automaticky dopočítají, blok se zarovná nahoru doprostřed

Horizontální zarovnávání asi není potřeba zvlášť rozvádět, záleží zkrátka na tom, jak je nastavený levý a pravý vnější okraj bloku. Pokud jsou stejně velké, např. 5 % a 5 % (procenta se vypočítávají ze šířky nadřazeného bloku), zatlačí to daný blok doprostřed.

Vertikální zarovnávání je mnohem složitější a lapidární konstatování, že margin-bottom:0 znamená, že daný blok bude vzdálený 0 pixelů od následujícího, je podmíněno tím, že a) horní vnější okraj (margin-top) následujícího bloku bude nulový b) následující blok bude k dispozici. Analogické je to s margin-top:0.

schéma
Na obrázku jsou světle hnědou barvou graficky znázorněny dva odstavce, které jsou vnořeny do dalších bloků. První odstavec má deklarováno margin: 2px, jenže shora není od okraje rodičovského bloku odsazen vůbec. Je to kvůli tomu, že od horního (ani dolního) okraje rodičovského bloku se margin nepočítá, platí padding rodičovského elementu. Zdola tento odstavec je pro změnu od sousedního odstavce vzdálen o celých 5 pixelů, protože při stanovení vzdálenosti mezi dvěma sousedními bloky rozhoduje to, čí margin je větší a ten se použije; spodní odstavec má deklarovaný pětipixelový vnější okraj.

Vertikální centrování

Je-li zapotřebí zarovnat nějaký blok uvnitř jiného bloku vertikálně do středu,…
schéma
…ideálně k tomu poslouží vlastnost padding. Jako na obrázku, kde se deklarací vnitřního okraje nebo-li paddingu (znázorněn zelenými šipkami) rodičovského bloku podařilo vertikálně vycentrovat objekt uvnitř rodičovského bloku; horizontálně se objekt zarovnal doleva, jak je jeho zvykem.

Padding však nepomůže v případě, kdy nepůjde přesně stanovit rozměry horního a dolního okraje a bude tedy nutné, aby si je prohlížeč sám rovnoměrně dopočítal. Jsou v podstatě dvě možnosti, jak toho dosáhnout. První možností je udělit rodičovskému prvku povahu buňky tabulky. Obsah buňky lze totiž bez potíží vertikálně zarovnávat pomocí vlastnosti vertical-align. V CSS by to tedy vypadalo nějak takto:

div#parent {height: 99px; display: table-cell; vertical-align: middle}

Toto řešení je jednoduché, elegantní, bohužel však nefunguje v Internet Exploreru, protože ten doposud nedokáže interpretovat tabulkové hodnoty vlastnosti display. To se změní až s nástupem osmé verze IE, nezbývá tedy nic jiného, než počkat a zatím vzít zavděk druhou možností, která spočívá v absolutním pozicování. Centrovaný prvek se nejprve absolutně napozicuje na úroveň poloviny výšky omezujícího bloku (tím nemusí být nutně rodičovský prvek) a následně se posune o polovinu své vlastní výšky nahoru.

div#parent {position: relative}
p#child {height: 6ex; position: absolute; top: 50%; margin-top: -3ex}

Tento způsob má ovšem to zásadní omezení, že je nezbytně nutné znát výšku centrovaného prvku, aby jej bylo možné pomocí margin-top posunout o polovinu jeho výšky nahoru.

Možná je i kombinace obou postupů, kterou představil Dušan Janovský. Jeho řešení je výhodné v tom, že není zapotřebí znát výšku centrovaného prvku! Aby však bylo dané řešení možno aplikovat i v novějších verzích IE, je nezbytné sáhnout po režimu zpětné kompatibility, což s sebou přinese řadu nevítaných změn.

Vertikální centrování stránky

Šířka prostoru, v němž se stránka nachází, je dána šířkou okna prohlížeče. Výška prostoru, v němž se stránka nalézá, je dána výškou jeho obsahu (tedy výškou oné stránky). Tento fakt si lze snadno ověřit tím, že se do adresního řádku prohlížeče zadá:

javascript:alert(document.body.offsetHeight)

Po odentrování se objeví číslo indikující výšku prvku body v pixelech.

Pro účely vertikálního vycentrování stránky v okně prohlížeče, je ovšem potřeba, aby prvek body měl výšku shodnou s výškou okna, resp. viewportu prohlížeče! To zařídí tento zápis:

html,body {height: 100%}

Teprve poté je možné pomocí CSS stránku zdárně vertikálně vycentrovat některým z výše zmíněných postupů. Obšírněji se touto věcí zabýval Petr Staníček. Uvedeného zápisu se mimochodem využívá i pro zarovnání patičky stránky ke spodnímu okraji okna.

Neprehliadnite: