Martin Michálek Martin Michálek  – 26. 11. 2020

Rozvržení typu masonry je ve webdesignu stejně populární jako zednická lžíce mezi zedníky.

Kodérky a kodéři jsou ovšem dneska nucení jej dělat pomocí JavaScriptu. Nativní implementace v CSS byla součástí našich snů už od příchodu flexboxu, ale plně to nevyřešil ani grid.

Teď už se ale blýská na lepší časy. Chystaná třetí verze specifikace CSS gridu totiž počítá s hodnotou masonry pro vlastnosti grid-template-rows/columns:

.container {
  display: grid;
  grid-template-rows: masonry;
}

Zatím to má podporu jen v Nightly verzi Firefoxu, ale předpokládáme, že se to ujme a že nás to zbaví dalšího nadbytečného javascriptového pluginu.

Skvěle to (jako vždy) popisuje Rachel Andrew v textu Native CSS Masonry Layout In CSS Grid na Smashing Magazine, ze kterého tady budu vycházet.

Co je to „masonry“?

Určitě zde jsou tací, kteří o masonry layoutu nic moc nevědí. „Masonry“ je v překladu zdivo, takže jde o „zděné“ rozvržení stránky.

Když se položky ve zděném rozvržení přesunou na další řádek, nezarovnávají se do rovné linky, ale přesunou se nahoru do mezer, které zanechají kratší položky v prvním řádku. Je to podobné jako u jedné z vlastností CSS Gridu, automatického umístění (autoplacement), ale bez přísného dodržení mřížky pro řádky.

Však se podívejte na obrázek výše, z toho to bude asi vidět lépe. Hlavní směr typického masonry layoutu je inline, tedy po řádcích.

V současnosti se tyto typy rozvržení dělají pomocí dnes už legendární javascriptové kompomenty Masonry od Davida DeSandra.

Autorovi všechna čest, ale je nutné si přiznat, že z pohledu vykreslovacího (ale i načítacího) výkonu stránky nebude takto razantní ovlivňování layoutu JavaScriptem nikdy optimální. Tohle má prostě dělat prohlížeč.

Masonry v CSS gridu

Masonry layout budeme podle specifikace definovat pomocí grid-template-rows:masonry nebo grid-template-columns:masonry, podle toho, zda si pro „zdění“ vybereme vodorovný nebo svislý směr.

Směr definovaný pomocí masonry se pak bude označovat jako osa zdiva. Druhá osa bude mít stopy mřížky definované jako normální. To bude osa mřížky.

Přikládám CodePen, ale v době psaní bude fungovat jen ve zmíněném Firefox Nightly, takže neuškodí, když si jej stáhnete.

V uvedeném prohlížeči si můžete pohrát s hlavním kouskem kódu, který vypadá takto:

.container {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Raději to vysvětlím:

Výsledek tohodle zápisu nicméně bez Firefox Nightly lépe uvidíte na obrázku. Tady je.

Je to nativní. Není to krásné?

Napiš řádek kódu,
postav třeba zeď.
Zpívej přitom ódu,
začni s tím hned teď.

Po básnické vsuvce, vyvolané vidinou světa bez další javascriptové knihovny, pojďme dál.

Další vlastnosti CSS gridu v masonry? No jasně!

Vzhledem k tomu, že jsme v systému rozvržení pomocí CSS gridu, můžeme používat i další vlastnosti:

  • Stále můžeme porušit automatické umísťování a konkrétní položku vložit na konkrétní místo mřížky. Viz prvek .positioned v tomto CodePenu od Rachel Andrew.
  • Je samozřejmě dovoleno používat i roztažení prvků do více buněk mřížky. To je zase vidět na prvku .landscape v jiném CodePenu.

masonry-auto-flow, kontrola toku položek

Tato vlastnost ještě není naprogramovaná ani ve Firefox Nightly, ale je podobná existující grid-auto-flow. Prostě ovlivňuje, v jakém pořadí se budou položky do zděného rozvržení sázet.

  • Ve výchozím stavu položku prohlížeč vloží do sloupce s největším prostorem.
  • Hodnota next – umístí položku na další místo na ose mřížky.
  • Hodnota ordered – layout bude vždy v pořadí, v jakém jsou položky v dokumentu, pokud není řečeno jinak pomocí vlastnosti order.

Zarovnání pomocí justify-tracksalign-tracks

V layoutu typu masonry potřebujeme i dvě nové zarovnávací vlastnosti.

Jako by nám nestačily ty desítky, co jich už máme, řekl by bručoun. Ale neměl by pravdu, tento typ zarovnání je úplně nový a nic adekvátního zatím nemáme.

Pokud máte v kontejneru mřížky více prostoru ve směru rozloženém pomocí masonry, zjistíte, že se položky zarovnají na začátek kontejneru. Počáteční hodnota vlastnosti align-tracks je totiž start.

Další možnosti jsou podobné jako u vlastností align-contentjustify-content (např. end nebo asi i space-between) s několika modifikacemi:

  • Hodnota normal – u těchto vlastností se chová jako start.
  • Hodnota stretch - položky automatické velikosti v rozložení se roztáhnou.

Podpora v prohlížečích a implementace

Standardizátoři mají CSS Grid Level 3 zatím rozpracovaný. V téhle fázi je tedy potřeba, aby vývojářky a vývojáři neváhali dávat zpětnou vazbu.

Jak už jsem zmínil – v době psaní je tato skvělá nová věc podporovaná jen v Nightly verzi Firefoxu. I tam je ale potřeba zapnout vlaječku layout.css.grid-template-masonry-valueabout:config.

Řešit fallbacky bude v případě nativní implementace technicky snadné řešit, protože máme podmínku podpory – @supports:

@supports (grid-template-rows: masonry) {
  .container {
    display: grid;
    grid-template-rows: masonry;
  }  
}

Je samozřejmě otázkou, jak může vypadat náhradní řešení z vizuálního pohledu.

Osobně nicméně věřím, že po připomínkovém řízení ke specifikaci dojde k implementaci v Chrome a odvozených prohlížečích a pak chvíli čekání na Safari, jak už to ve světě dnešního vývoje webů chodí.

Takže podpora naprosté většiny prohlížečů zde může přijít relativně brzy, ale teď je na nás, abychom to zkoušeli a připomínkovali.

Další možnosti jak řešit masonry

Do doby než se dokončí specifikace a prohlížeče nativní masonry naimplementují, přidávám sem také seznam alternativních metod.

JavaScriptové pluginy Davida DeSandra

Existují dvě varianty:

  • Masonry
    „JavaScript grid layout library“ je použitelná s jQuery nebo také s čistým JavaSciptem. Má spoustu možností nastavení. 24 kB dat po minifikaci, 8 kB po gzipu.
  • Colcade
    Jedna osmina velikosti Masonry. Na druhou stranu neumí některé funkce sesterské knihovny jako spojování sloupečků (multi-column-spanning) nebo přechody (transitions). Za tip děkujeme Honzovi z komentářů.

Další metody dvě věci společné. Na rozdíl od DeSandrova pluginu nepotřebují JavaScipt. A řeší vždy jen část scénářů, pro které zděný layout vývojáři používají.

Vícesloupcový layout

CSS Multi-column Layout je možné použít pro účely jednoduchého Masonry:

.container {
  column-count: 4;
  column-gap: 10px;
}

Nevýhodou je to, že směr layoutu bude vždy po sloupcích, nikoliv po řádcích. Prohlížeč také – díky povaze vícesloupcové sazby – nebude trápit, když poslední sloupec zůstane vyplněný jen z malé části.

CSS Grid a husté umístění

Vlastnost grid-auto-flow může mít hodnotou dense, která zajistí že prohlížeč může vyplnit mezery změnou pořadí prvků.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
  gap: 10px;
}

Nevýhoda? Pořád jde o vykreslení do mřížky, takže mezi jednotlivými položkami většinou zůstávají nevyplněné mezery.

Flexbox, :nth-childorder

Tobias Ahlin Bjerrome se pokusil o řešení flexboxem, selektorem :nth-child(n)vlastností order:

/* Render items as columns */
.container {
  display: flex;
  flex-flow: column wrap;
}

/* Re-order items into rows */
.item:nth-child(3n+1) { order: 1; }
.item:nth-child(3n+2) { order: 2; }
.item:nth-child(3n)   { order: 3; }

/* Force new columns */
.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

Je to plné dobrých nápadů, relativně dobře to funguje, ale ne na všech rozlišeních. Navíc je složité to nastavoval pro různý počet sloupců v layoutu.

Další možná řešení už budu jmenovat jen stručně:

Pokud znáte další řešení, které pomůže ostatním čtenářkám a čtenářům, než prohlížeče začnou podporovat nativní variantu, neváhejte se ozvat v komentářích.

Komentáře

Váš názor? Vaše zkušenosti? Našli jste chybu?

Dotazník: Jak
se vzděláváte online?
5 minut vašeho času.
Velká pomoc pro nás.
Vyplnit →