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

CSS masonry snad jednou bude součástí specifikace CSS gridu.
Kodérky a kodéři jsou ovšem dneska nucení se s ním vypořádat 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 však snad blýská na lepší časy. Chystaná třetí verze specifikace gridu totiž počítá s možností zápisu hodnoty masonry u vlastností grid-template-rows/columns:
.container {
display: grid;
grid-template-rows: masonry;
}
Subgrid má zatím bohužel podporu jen ve verzi Firefoxu Nightly. Je ale možné, že se ujme a že nás zbaví dalšího nadbytečného javascriptového pluginu.
Aktuálně ovšem tuto funkci na webech používat nemůžeme, proto se v článku kromě budoucnosti (nativní implementace v CSS) věnujeme i současnosti (řešení pomocí JS komponent).
Skvěle to (jako vždy) popisuje Rachel Andrew v textu „Native CSS Masonry Layout In CSS grid“ ve Smashing Magazine, ze kterého tady budu vycházet. vrdl.in/smmas
Co je to „masonry“?
Určitě zde jsou tací, kteří o layoutu masonry nic moc nevědí. „Masonry“ je v překladu zdivo, takže jde o „zděné“ rozvržení stránky.
Masonry na webu Erika Johanssona. Jediná vada na kráse je vykreslení pomocí klientského JavaScriptu. erikjo.com/work
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, na něm to asi pochopíte nejlépe. Hlavní směr typického masonry je inline, tedy po řádcích.
V současnosti se tyto typy rozvržení dělají pomocí dnes už takřka legendární javascriptové komponenty „Masonry“ od Davida DeSandra.
vrdl.in/mas
Autorovi všechna čest, je však 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č a autoři to mají definovat v CSS.
Masonry v CSS gridu
Masonry doufejme jednou budeme zapisovat podle specifikace deklaracemi 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 tuto verzi prohlížeče pro zkoušení nových vlastností stáhnete.
CodePen: vrdl.in/i2dgv
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:
display:griddefinuje layout do mřížky.gap:10pxnabádá prohlížeč k vykreslení desetipixelové mezery mezi buňkami.grid-template-columns:repeat(4,1fr)vykreslí čtyři stejně široké sloupce mřížky. Viz zápisrepeat().grid-template-rows:masonryzařídí to zděné kouzlo. Řádky nebudou zarovnané podle osy, ale nalepí se na položky výše a přeskupí se. Viz vlastnostgrid-template-rows.
Výsledek tohoto zápisu nicméně bez Firefox Nightly lépe uvidíte na následujícím obrázku.
Nativně vykreslený layout typu masonry. Zdroj: CodePen Rachel Andrew.
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é chvilce, 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
.positionedv tomto CodePenu od Rachel Andrew. vrdl.in/0yh1j - Je samozřejmě dovoleno používat i roztažení prvků do více buněk mřížky. To je zase vidět na prvku
.landscapev jiném CodePenu. vrdl.in/ar9ex
Vlastnost 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 vloží prohlížeč položku 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í vlastnostiorder.
Zarovnání pomocí vlastností justify-tracks a align-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 zarovnání jsou podobné jako u vlastností align-content a justify-content (např. end nebo z podstaty věci také space-between), s několika modifikacemi:
- Hodnota
normal– u těchto vlastností se chová jakostart. - 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 únoru 2022 byla tato skvělá nová věc podporovaná jen ve verzi Firefoxu Nightly. I tam je ale potřeba zapnout vlaječku layout.css.grid-template-masonry-value v about:config.
Řešit fallbacky bude v případě nativní implementace relativně snadné, 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.
Doufejme, že o těchto náhradních řešeních nebudeme muset dlouho přemýšlet a po připomínkovém řízení ke specifikaci dojde k implementaci v Chromu 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í.
Další možnosti, jak řešit masonry
Do doby, než se dokončí specifikace a prohlížeče nativní masonry implementují, 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 JavaScriptem. Má spoustu možností nastavení. 24 kB dat po minifikaci, 8 kB po gzipu. vrdl.in/mas - Colcade
Jedna osmina velikosti Masonry. Na druhou stranu neumí některé funkce sesterské knihovny, jakými jsou třeba spojování sloupečků (multi-column-spanning) nebo přechody (transitions). vrdl.in/colca
Další metody alternativního řešení zděného layoutu mají dvě věci společné. Na rozdíl od DeSandrova pluginu nepotřebují JavaScript. 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č se také – kvůli povaze vícesloupcové sazby – nebude trápit tím, když poslední sloupec zůstane vyplněný jen z malé části.
CodePen: vrdl.in/y5b7l
CSS grid a zahuštěné umístění
Vlastnost grid-auto-flow může mít hodnotu 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.
CodePen: vrdl.in/km26b
Flexbox, :nth-child a order
Tobias Ahlin Bjerrome se pokusil o řešení flexboxem, selektorem :nth-child(n) a vlastností order. vrdl.in/tobmas
/* 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 ve všech rozlišeních. Navíc je složité to nastavovat pro různý počet sloupců v layoutu.
CodePen: vrdl.in/dghb6
Související
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.