Chcete zobrazit modální dialog ve stránce, který je vždy centrovaný do středu obrazovky? To asi budete potřebovat hodně skriptů na jeho otevření, vypočtení velikosti, vycentrování a jeho udržování v obraze (např. při otočení telefonu). Viz demo.
Ale co kdyby tohle všechno šlo udělat jen pomocí HTML a CSS, nebylo by to super?
A představte si, že to jde!
TL;DR
Pokud neradi čtete text a raději se podíváte na demo, můžete prostudovat jeho zdrojový kód, kde je vše popsáno. K dispozici je jednoduchý dialog s pevným umístěním a nebo dialog vždy centrovaný pomocí Flexboxu.
Poznámka: všimněte si drobného rozdílu v tom, že pro pevné umístění je potřeba použít outer
a inner
DIVy, aby šlo správně nastavit max-height
, zatímco u flexboxu je nutno použít jen inner
, protože naopak s outer
DIVem max-height
nefunguje správně!
Otevření dialogu
Přeci na otevření dialogu musí být potřeba onclick handler, ne?
To není úplně pravda: když totiž do odkazu uvedete jen hash (#) znak a ID, přidá se toto ID do URL, ale jinak se stránka nezmění.
Pouze se na stránce označí element s příslušným ID. Označení jednak probíhá nakrolováním na daný prvek a současně označením prvku pro CSS, které pak může použít a pomocí selektoru :target
daný prvek zvýraznit.
Pokud tedy necháme dialog skrytý a pomocí :target
ho zobrazíme, bude to vypadat, že se dialog zobrazil po kliku na odkaz.
<a href="#dialog">Otevři dialog</a>
#dialog { display: none; } #dialog:target { display: block; }
Zavření dialogu
Jak udělat zavření dialogu? Stačí přesměrovat stránku na jiný hash, nejlépe prázdný:
<a href="#">Zavři dialog</a>
CSS se pak o vše postará a dialog zase skryje (díky tomu, že ztratí selektor :target
).
Pevná pozice
Pokud stačí zobrazit dialog na pevné pozici (nejlépe vlevo nahoře), stačí pomocí position:fixed
správně nastavit pozici a rozměry:
position: fixed; transform: translate(0,0); width: auto; left: 0; right: 0; height: auto; top: 0; bottom: 0; z-index: 990;
Pomocí width
, height
, top
, apod. nastavíme rozměr dialogu přes celou stránku. Z-index
použijeme k tomu, aby se dialog zobrazil nad stránkou a nic do něj nezasahovalo. Pomocí transform
ještě ošetříme chyby v některých webkitech (Safari, Chrome), které mají občas problémy s pevně umístěnými prvky.
Problém ale nastave v případě, že obsah dialogu se nevejde na stránku, protože pak bude prostě vytékat dolu, ale jelikož je pevně umístěn, nepomůže nám skrolování stránky. Kvůli tomu bude potřeba ještě obsah dialogu obalit jedním DIVem, kterému nastavíme maximální výšku a zapneme skrolování:
#modal-inner { height: auto; max-height: 100%; overflow-x: hidden; overflow-y: auto; }
Nejprve nastavíme automatickou výšku, aby se pro menší obsah dialog přizpůsobil. Pak nastavíme max-height
na 100%, aby nikdy nemohl přesáhnout oblast obrazovky a následně pomocí overflow
umožníme zobrazení svislého posuvníku.
Vždy na středu
Pokud naopak chcete, aby byl dialog vždy uprostřed obrazovky, není potřeba složitě počítat jeho rozměry a neustále ho přemisťovat pomocí JavaScriptu.
Úplně stejně nám k tomu poslouží Flexbox, který umí centrovat prvky v prostoru – zcela automaticky. Nevýhoda je, že jeho zápis je trochu složitější a na IE9 a starších vůbec nefunguje, ale to se dá většinou oželet.
Pokud modální dialog zobrazíme pomocí display:flex
místo display:block
, všechny vnořené prvky se automaticky začnou chovat jako flex-item, na které můžeme aplikovat některé speciální CSS hodnoty:
#modal:target { display: block; /* IE9 and older */ display: -webkit-box; /* iOS6+, Safari */ display: -moz-box; /* Firefox 4 - 19 */ display: box; /* Opera 12 - 14 apod.*/ display: -ms-flexbox; /* IE10 */ display: flexbox; /* ostatní starší */ display: -webkit-flex; /* iOS7.1+ */ display: flex !important; /* Firefox 22+, Chrome 21+, IE11, Opera 15+ */ }
Pro vycentrování obsahu dialogu pak stačí použít:
#modal { -webkit-box-align: center; -moz-box-align: center; box-align: center; -ms-flex-align: center; flex-align: center; -webkit-align-items: center; -webkit-align-content: center; align-items: center; align-content: center; -webkit-box-pack: center; moz-box-pack: center; box-pack: center; -ms-flex-pack: center; flex-pack: center; -webkit-justify-content: center; justify-content: center; }
Díky tomu bude dialog vždy na středu jak vertikálně tak horizontálně (pokud je menší než 100%) nezávisle ne změně velikosti stránky.
Pokud vás zajímá, proč je zápis Flexboxu tak složitý, přečtěte si o historii Flexibilního layoutu.
Pro ošetření vytékání je potřeba provést to samé jako výše, jen není potřeba další obal – stačí max-height
a overflow
nastavit přímo do flex-item.
Další vylepšení
Další vylepšení, jako je stínované pozadí dialogu, odsazení od okrajů či kulaté rohy si můžete nastudovat ve zdrojových kódech demo ukázek:
- Dialog pomocí JavaScriptu (nedoporučeno používat)
- Dialog na pevné pozici
- Dialog na středu (Flexbox)