Lekce 9 - CSS grid - Principy a layout
V předchozí lekci, Grid systém od Flexbox Grid, jsme si ukázali, jak se pracuje s grid systémem od flexboxgrid.com.
V tomto CSS tutoriálu si představíme CSS grid systém a jakým způsobem jej můžeme využít k tvorbě layoutu webu.
Motivace
Aby se naše webové stránky dobře četly a používaly, je potřeba obsah na nich dobře rozložit. K tomu využíváme layouty (rozložení).
Layout stránky obvykle obsahuje hlavičku, tělo a patičku. Samozřejmě se ale může jednat o jakýkoli jiný layout, např. pokud budeme tvořit webovou hru Pexeso, bude layout stránky mřížka o několika řádcích a sloupcích kartiček.
K tvorbě layoutů se v současné době používají tři technologie:
- Flexbox - Flexbox je primárně jednorozměrný kontejner, určený pro organizaci prvků vedle sebe nebo pod sebe. Postačí nám na layouty jednoduchých webů. V našich kurzech jsme takto vytvořili layout např. v lekci Stylování hlavičky HTML stránky a flexbox. Složitější layouty můžeme tvořit tak, že použijeme více flexboxů.
- CSS grid - Grid je opět nativní systém zobrazení v CSS, který funguje podobně jako flexbox, jen je dvourozměrný. Jedná se tedy o mřížku. Pro jednoduché layouty je zbytečně složitý, pro složitější rozložení prvků na stránce nám naopak ušetří spoustu práce a to hlavně, když rozložení připomíná mřížku (což tak často je).
- Bootstrap grid/Flexbox grid - Bootstrap je populární CSS
framework třetí strany, který musíme do svých stránek prvně stáhnout
nebo na něj odkazovat. Obsahuje svůj vlastní systém pro tvorbu layoutů -
Bootstrap grid, který je složitostí a účelem někde mezi dvěma výše
zmíněnými. Zásadní rozdíl mezi Bootstrapem a řešením přes CSS je, že
Bootstrap styly se nenastavují v CSS, ale přímo v HTML pomocí atributů
class
. Tento přístup může být o něco rychlejší, ale zas vyžaduje užití externí knihovny. Již jsme si jej představovali v podobě Flexbox Grid, což je principiálně vlastně to samé řešení, jako používá Bootstrap.
Dnes se tedy zaměříme na komplexnější nativní řešení, kterým je CSS grid.
Co je CSS Grid?
CSS Grid je systém pro dvourozměrné uspořádání prvků na stránce. Vytvoří nám na daném obalovém elementu virtuální mřížku, do které můžeme umisťovat různé prvky a ovládat jejich rozmístění a rozměry.
Termín mřížka nebudeme zaměňovat s termínem tabulka, která v HTML neslouží pro rozložení celé stránky, ale jen pro prezentaci vybraných tabulkových dat.
HTML stránka
Jako první si připravíme stránku s několika elementy, které vložíme
do kontejneru <div>
:
<div class="container"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div>
Základy syntaxe
Podobně jako flexbox i grid aktivujeme pomocí vlastnosti
display
obalového elementu (kontejneru) a to jako:
display: grid
nebodisplay: inline-grid
v případě, že chceme, aby byla mřížka jako řádkový element (např. ji chceme umístit vedle dalšího obsahu).
Základní syntaxe vypadá takto:
.container { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 10px; }
Vysvětleme si použité vlastnosti:
grid-template-columns
- Nastavuje počet a rozměr jednotlivých sloupců mřížky. V příkladu výše vytváříme mřížku se třemi sloupci. Jednotkafr
označuje frakci (fraction), čímž udáváme, že každý sloupec bude mít stejnou velikost.grid-template-rows
- Určuje počet a rozměr jednotlivých řádků, podobně zde takto vytváříme dva řádky.gap
- Mezera mezi sloupci a řádky. Můžeme specifikovat zvlášť i mezeru mezi sloupci (column-gap
) a mezi řádky (row-gap
).
Abychom viděli, že se elementy opravdu uskupily do mřížky, přidejme si i barevné pozadí pro položky gridu:
.container > div { background: #b3deff; }
Selektor >
označí jen elementy
<div>
vložené přímo v gridu, na další elementy se pak
už aplikovat nebude.
Výsledkem je jednoduchá mřížka:
Funkce repeat()
Abychom nemuseli v CSS kódu neustále opisovat 1fr
, případně
jiné násobky frakcí, používá se často k definování sloupců a řádků
CSS funkce repeat()
. Ta bere dva parametry:
- kolikrát chceme danou hodnotu opakovat
- co chceme opakovat
Kód můžeme upravit do následující podoby, fungovat bude stále stejně:
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); gap: 10px; }
Pozicování elementů
V naší ukázce nyní máme šest elementů, které se automaticky postupně rozdistribuovaly do šesti buněk naší mřížky. Mřížka je ale opravdu virtuální a v některých buňkách nemusí být žádný element nebo naopak jeden element může být vložen přes více sloupců a řádků. Upravme náš HTML příklad do následující podoby:
<div class="container"> <div class="item1">1</div> <div class="item2">2</div> </div>
A CSS upravme takto:
.container { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 10px; } .container > div { background: #b3deff; } .item1 { grid-column: 1; grid-row: 2; } .item2 { grid-column: 2 / 4; grid-row: 1 / 3; }
Výsledek:
Element 1 je nyní vložený v prvním sloupci a druhém řádku. Element 2 je vložený v druhém sloupci a prvním řádku a je roztažený až do druhého řádku a třetího sloupce.
Může být matoucí, že při roztahování přes více řádků a sloupců uvádíme vždy o 1 vyšší sloupec a řádek. Důvodem je, že ve skutečnosti specifikujeme "čáru" (tzv. grid lines), kam až se má sloupec/řádek natáhnout. Situaci určitě pochopíte z obrázku níže, kde jsou nakresleny a očíslovány pomyslné čáry, podle kterých pak určujeme, kam se má element roztahovat:
Zápis:
grid-column: 2 / 3;
je pak zkráceným zápisem:
grid-column-start: 2; grid-column-end: 3;
Udávání velikosti
Velikost sloupců a řádků bychom mohli zadat i v px
, obvykle
ale chceme, aby se buňky roztahovaly s šířkou stránky. Výhodné je
jednotky px
míchat s fr
, čímž můžeme např.
vytvořit klasický layout s hlavičkou, sidebarem a patičkou, kde snadno
roztáhneme zbytek mřížky přes zbytek stránky:
grid-template-columns: 100px 1fr 1fr;
Výsledek:
Příklad - Tvorba layoutu
Konečně máme dostatek znalostí na praktickou ukázku layoutu Pomocí CSS grid vytvořme nejklasičtější layout webu.
HTML:
<div class="container"> <nav>navigace</nav> <aside>sidebar</aside> <article>obsah</article> <footer>patička</footer> </div>
CSS:
.container { display: grid; grid-template-columns: 200px 1fr; grid-template-rows: 50px 1fr 50px; gap: 10px; } .container > nav, aside, article, footer { background: #b3deff; } .container > nav { grid-column: 1 / 3; grid-row: 1; } .container > aside { grid-column: 1; grid-row: 2 / 3; } .container > article { grid-column: 2 / 3; grid-row: 2; } .container > footer { grid-column: 1 / 3; grid-row: 3; }
Výsledek:
Výsledkem je navigace vysoká 50px
, zabírající 100%
stránky. Poté následuje 100px
široký sidebar a obsah, který
zabírá zbytek šířky. Celý tento řádek zabírá také tolik výšky,
kolik je potřeba. Následuje patička vysoká 50px
a široká 100%
stránky.
Pojmenování oblastí mřížky
Často, např. i v případě našeho layoutu, mají určité části
mřížky určitý význam. CSS nám umožňuje tyto názvy definovat a pak
pracovat jen s nimi, namísto čísel čar. Slouží k tomu CSS vlastnost
grid-template-areas
. Ukažme si, jak by to vypadalo pro příklad
layoutu výše:
.container { display: grid; grid-template-columns: 200px 1fr; grid-template-rows: 50px 1fr 50px; gap: 10px; grid-template-areas: "nav nav" "aside article" "footer footer"; } .container > nav, aside, article, footer { background: #b3deff; } .container > nav { grid-area: nav; } .container > aside { grid-area: aside; } .container > article { grid-area: article; } .container > footer { grid-area: footer; }
Pokud některý prostor zasahuje do více buněk, napíšeme jeho název jednoduše vícekrát. Pak si všimněte, že v dalších stylech používáme již názvy těchto prostorů namísto složitého vymezování počátečních a koncových sloupců a řádků.
Výsledek je stejný:
Bonus - Další možnosti rozměrů
Na každou součást CSS by se dal v podstatě napsat celý kurz. Nemá smysl se je všechny učit, člověk se musí naučit hlavně si dohledávat informace, když je potřebuje. Na závěr si udělejme alespoň představu o dalších možnostech gridu.
Vlastnosti
grid-auto-rows
a grid-auto-columns
Kromě template
(šablonových) řádků a sloupců můžeme
definovat i tzv. automatické auto
řádky a sloupce. To jsou styly
pro řádky a sloupce, které se vytvoří, když do kontejneru přidáme více
elementů, než kolik má definováno buněk v mřížce. Pro tyto automaticky
přigenerované sloupce a buňky můžeme nastavit velikosti pomocí vlastností
grid-auto-rows
a grid-auto-columns
. Upravme náš
příklad s čísly:
<div class="container"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> </div>
A do CSS přidejme:
grid-auto-rows: 100px;
Výsledek:
Vidíme, že sedmý element se přidal do nového třetího řádku, který
má výšku definovanou na 100px
.
CSS funkce minmax()
Podobně můžeme použít k definici výšky CSS funkci
minmax()
, díky které můžeme nastavit jak minimální, tak
maximální rozměr. Funkci můžeme použít jak pro řádky, tak pro sloupce,
a jak pro template, tak pro auto varianty. Ukažme si příklad:
.container { display: grid; grid-template-columns: minmax(auto, 1fr); }
V tomto příkladu minmax(auto, 1fr)
říká, že sloupce mohou
mít jakoukoli šířku, která je nejméně auto
a nejvíce
1fr
. Hodnota auto
znamená, že šířka bude alespoň
tak velká, jak je potřeba pro obsah, a 1fr
znamená, že šířka
může zabírat celý zbývající prostor.
auto-fill
a
auto-fit
Při užití funkce repeat()
můžeme zadat kromě pevného
čísla také hodnoty auto-fit
nebo auto-fill
.
Automaticky se pak vygeneruje takový počet buněk, aby se do mřížky dané
elementy vešly. Ukažme si na závěr pro představu i komplexnější
příklad skombinovaný s minmax()
:
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
Tímto způsobem vytvoříme mřížku, která automaticky přidává a
odebírá sloupce podle velikosti obrazovky, přičemž minimální šířka
sloupce je 200px
. Hodnota auto-fill
způsobí
doplnění volného prostoru neviditelnými buňkami, zatímco
auto-fit
se zaměřuje na rozšiřování již existujících
buněk.
V další lekci, Úvod do Bootstrapu, se uvedeme do frameworku Bootstrap a ukážeme si jeho základní principy.