Martin Michálek Martin Michálek  – 21. 1. 2021

Vlastnost display slouží k určení způsobu vykreslení prvku. Může to být i relativně komplikovaná věc a má spoustu nových hodnot.

Vy, kteří znáte její základní hodnoty jako block nebo inline možná budete překvapení, že od roku 2020 zde máme novou verzi specifikace, která přidává řadu dalších možností – „CSS Display Module Level 3“. vrdl.in/w3disp

Ale víte co? Začneme jednoduchým přehledem nejužitečnějších hodnot. Většinu z nich asi znáte.

Hodnota Jak se zobrazuje
inline Řádkový element, který netvoří zalomení před sebou nebo po sobě. (výchozí)
block Blokový element. Zalomí řádky před sebou i po sobě.
inline-block Vnitřně se jedná o blokový element, zvnějšku inline, který netvoří zalomení.
flex, inline-flex Vytvoří flexboxové rozvržení. Inline varianta nezalomí řádky před a po.
grid, inline-grid Vytvoří rozvržení do mřížky. Inline varianta opět nezalomí řádky.
table, inline-table Rozvržení do tabulky. Inline varianta opět tvoří tabulku v řádce.
none Nevykreslí prvek, ale ani jeho potomky.

V tabulce zdaleka nejsou všechny možnosti a popsány všechny jejich specifické vlastnosti, nástrahy a vychytávky. Proto čtěte dál.

Víte například, že…?

V CSS je stále těžší najít vlastnost, která by byla snadná k pochopení a naučení.

Možná to překvapí i vás, zkušenější, ale jak vidíte nebo brzy uvidíte docela široký záběr člověk potřebuje i pro vstřebání vlastnosti display. Pojďme se teď podívat do jejího světa.

Vnitřní a vnější zobrazení

První věc, kterou si musíme uvědomit, je holý fakt, že nově podle specifikace existují dva typy zobrazení:

  • Vnitřní zobrazení
    Hodnota vlastnosti display určuje, jak prohlížeče rozloží potomky prvku. Sem patří hodnoty jako flex, grid nebo table.
  • Vnější zobrazení
    Hodnota definuje, jak se sám prvek podílí na rozložení stránky. Pohled zvenčí. Toto určují hodnoty jako inline, block nebo none.

Máte? Výborně. Toto se nám bude hodit, až budeme hovořit o hodnotách pro více klíčových slov.

Vnější zobrazení

Vnější zobrazení v podstatě určuje roli stylovaného boxu v uspořádání toku stránky.

Do tohoto typu zobrazení patří následující hodnoty:

  • inline
    Vytvoří boxík, který je „inline-level“, řádkový. Před sebou a po sobě nic nezalomí, prostě se vykreslí do řádky.
  • block
    Vygeneruje boxík, který je „block-level“. Zjednodušeně to znamená, že se vykreslí do celé šířky rodiče a zalomí řádky před sebou i po sobě.
  • inline-block
    Generuje boxík, která se zvenčí chová jako řádkový a uvnitř generuje vždy nový blokový kontext. Mimochodem, specifikace s touto hodnotou do budoucna počítá jen jako jiným zápisem pro dvojici klíčových slov inline flow-root. O tom píšu později.
  • run-in
    Vygeneruje typ „inline-level“ boxu se zvláštním chováním – pokusí se sloučit do následujícího blokového prvku. Pokud za „run-in“ prvkem následuje blokový prvek, „run-in“ se stane jeho prvním inline boxem. Pokud bude následovat inline pole, stane se z „run-in“ prvku blokový.

V CodePenu si můžete vyzkoušet všechny možnosti.

Varianta s display run-in v mé ukázce chybí, není totiž podporovaná jinde než v Internet Exploreru (!). V tomto dědečkovi mezi prohlížeči nefunguje CodePen, takže byste z ukázky nic neměli. Viz podpora na CanIUse.com. caniuse.com/run-in

Vnitřní zobrazení

Hodnoty vnitřního zobrazení zapínají uvnitř dotčeného prvku nový kontext formátování (k tomu se v CSS používá pojem „formatting context“). No a ten mívá vliv na způsob vykreslení vnitřních prvků, případně na použití dalších vlastností na nich.

  • flow
    Hodnota flow zapíná formátování tokem („flow layout“), což je běžný způsob zobrazení, který automaticky zapnou hodnoty block, inlineinline-block. Pokud vím, toto zatím není v prohlížečích podporováno, nicméně jde o výchozí režim rozvržení v CSS.
  • flow-root
    Vytvoří kontejner blokového kontextu (jako display:block) a rozloží jeho obsah pomocí toku (flow layout). Hodnota flow-root ale vždy generuje nový kontext formátování bloku pro svůj obsah, takže není například nutné mazat „floaty“ pomocí „clearfixu“. Na této hodnotě je zajímavé, že ji podporují všechny moderní prohlížeče. Internet Explorer nikoliv. caniuse.com/flow-root
  • flex
    Zapíná formátovací kontext flexboxu. Ze stylovaného prvku udělá flex kontejner a z přímých potomků flex položky. Podporováno všude.
  • grid
    Spouští formátovací kontext gridu. Ze stylovaného prvku udělá kontejner mřížky a z přímých potomků její položky. Podporováno všude.
  • table
    Udělá z prvku tabulku. V tomto případě jsou zde ale dva „kontejnery“. display:table generuje kontejner tabulky, který vytvoří kontext formátování bloku a obsahuje dodatečně vygenerovaný rámeček tabulky, který vytvoří její kontext formátování.
  • ruby
    Tohle je exotické a pro středoevropské prostředí nepotřebné. „Ruby anotace“ jsou krátké řady znaků umístěné vedle základního textu, které se používají ve východoasijské typografii jako vodítko pro výslovnost.

Připravil jsem dva vysvětlující CodePeny, na kterých si můžete otestovat to, co vidíte na obrázku.

V prvním máme jednoduše a bez layoutu umístěné tři prvky v jednom rodiči.

display:flow zatím nemá v prohlížečích podporu, ale jako by tam byla… „Tokové“ je totiž výchozí zobrazení.

Zajímavější bude druhý CodePen. Všechny tři vnitřní prvky jsou „tekoucí“, floatové:

.container p {
  float: left;
}

Výsledek vidíte na obrázku.

  • Běžné tokové zobrazení (display:flow) floaty obalit neumí, potřebovali bychom už zmíněný „clearfix“.
  • display:flow-root floaty obalí, vždy vytvoří nový kontext formátování bloku.
  • Na display:flexdisplay:grid nemají floaty žádný vliv.
  • Na vnitřní prvky v display:table floaty vliv mají, protože rodič je zde v běžném tokovém kontextu formátování bloku.

Pojďme ještě projít několik specifických hodnot.

Generování boxů se značkami: list-item

Zápis display:list-item způsobí, že element vygeneruje pseudoprvek ::marker.

Pokud není zadána žádná hodnota typu vnitřního zobrazení, výchozí bude tokové – jako display:flow. Pokud není zadána žádná hodnota typu vnějšího zobrazení, bude výchozí typ blokový – display:block.

Náš kontejner díky tomu můžeme stylovat, jako by to byl prvek <ul> nebo <ol>:

.container {
  list-style-type: square;
}

Podpora display:list-item jde napříč všemi prohlížeči. caniuse.com

První příklad na následujícím obrázku ukazuje zobrazení typu list-item.

Druhou a třetí hodnotu z obrázku probereme hned v následující části.

Schování prvků: nonecontents

Ke všem možným metodám ovlivnění vykreslování boxíků na obrazovku musíme přidat i metody nevykreslování. K tomu slouží následující dvě hodnoty vlastnosti display.

  • none
    Element ani jeho potomkové se na obrazovku prostě nevykreslí.
  • contents
    Element se na obrazovku nevykreslí, ale jeho potomkové ano.

Zobrazení typu contents funguje tak, jako by byl ve DOM stromu nahrazen jeho obsahem (včetně pseudoprvků jako ::before::after). Podle všeho však toto zatím není správně implementováno ve všech prohlížečích.

Podpora nezobrazení pomocí none je samozřejmě plná. Hodnotu contents zvládají všechny prohlížeče kromě Internet Exploreru, ale podle webu CanIUse je s ní spojeno několik chyb v prohlížečích vycházejících z jádra Chromium, které souvisejí s přístupností. caniuse.com

Typy zobrazení pro vnitřní rozvržení: table-*ruby-*

Modely zobrazení, které vynucují vnitřní rozvržení, jako je display:tabledisplay:ruby, mají složitou strukturu s několika různými rolemi, které mohou jejich potomci plnit.

Jak je uvedeno výše, zápis display:table sice vytvoří kontejner tabulky, ale ten vytvoří kontext formátování bloku. Nedosáhneme tím tedy tabulkového zobrazení. K tomu bychom potřebovali další prvky, které reprezentují řádky a buňky tabulky se správnými hodnotami vlastnosti display (table-row, table-cell…).

Podobné je to display:ruby, jen ty vnitřní prvky jsou jiné.

Hodnoty s více klíčovými slovy

Tohle je nová věc, do specifikace přidaná v druhé polovině roku 2020. Zatím to zvládá jen Firefox, ale věnovat se tomu musíme. Proč? Protože se mi to líbí.

Vzpomínáte si, když jsem psal o různých typech zobrazení – vnitřním a vnějším? Pokud ne, rychle proskenujte začátek tohoto textu nebo jeho nadpisy. Pak pochopíte, proč mi víceslovné hodnoty pro vlastnost display dávají smysl.

Výše uvedené hodnoty lze totiž brát jako zkratky pro víceslovná označení vnitřního, vnějšího nebo speciálního zobrazení.

Zkratka Plný zápis Co se generuje
none - nic
contents - prvek vynechán, generují se potomkové
block block flow blokový box
flow-root block flow-root blokový box, který vždy vytváří nový kontext formátování bloku
inline inline flow inline (řádkový) box
inline-block inline flow-root inline (řádkový) box, který vždy vytváří nový blokový kontext
run-in run-in flow run-in box (inline box se speciálními pravidly)
list-item block flow list-item blokový box s přídavnou značkou položky seznamu
inline list-item inline flow list-item inline box s přídavnou značkou položky seznamu
flex block flex blokový kontejner flexu
inline-flex inline flex inline kontejner flexu
grid block grid blokový kontejner mřížky
inline-grid inline grid inline kontejner mřížky
table block table blokový obalový rámeček tabulky
inline-table inline table inline obalový rámeček tabulky

Z tabulky je to asi zřejmé, ale pro jistotu ještě uvádím tři příklady:

  • display:block označuje blokový prvek (block), který je umístěný v běžném toku dokumentu (flow).
  • display:inline-flex definuje kontejner flexboxu (flex), který je umístěný v řádku (inline).
  • display:list-item vykreslí prvek seznamu (list-item), který je umístěný v běžném toku (flow) a zároveň je blokový (block).

Také se těšíte, až to budou umět všechny prohlížeče? Zatím jen Firefox, na ostatní se čeká. Podporu sledujte na CanIUse. caniuse.com (hledejte „display: Multi-keyword“)

A to je k vlastnosti display vše, děkuji za pozornost.

Text časem doplním o příklady z praxe a ještě rozvedu ten tabulkový layout. Pokud máte po ruce zajímavá využití novějších hodnot – jako flow-root, contents nebo run-in, budu rád, když je přidáte do komentářů.