Były takie czasy kiedy tabelke kojarzono z trzonem layoutu strony internetowej. Czasy te jednak minęły bezpowrotnie. Współcześnie dominującym typem layoutu jest strona internetowa „na divach”, czyli model, w którym wykorzystuje się elementy blokowe div i właściwość float aby stworzyć kontenery dla treści i grafik przedstawianych na naszej witrynie.
Niestety nie jest to model doskonały. Aby nadąrzyć za trendami w projektowaniu trzeba często sięgać po pozycjonowanie absolutne lub relatywne. Sam model strony „na divach” posiada również liczne wady jak chociażby częstą konieczność drobiazgowego kalkulowania dostępnej przestrzeni.
Dodatkowo znane html5 tagi <header>, <article> itp. nie pomagają w tym aspekcie, jako że same pozostaję częścią treści dokumentu (kodu html). Co więc nam pozostaje? Spójrzmy na to co przygotowuje dla nas W3C.
display:grid;
W3C w Editor’s Draft z 2.08.2012 pokazuje jak pewnie wyglądać będzie przyszłość tworzenia stron www.
Grid Layout contains features targeted at web application authors. The Grid can be used to achieve many different layouts. It excels at dividing up space for major regions of an application, or defining the relationship in terms of size, position, and layer between parts of a control built from HTML primitives.
Like tables, the Grid enables an author to align elements into columns and rows, but unlike tables, the Grid doesn’t have content structure, and thus enables a wide variety of layouts not possible with tables. For example, the children of the Grid can position themselves with Grid lines such that they overlap and layer similar to positioned elements.
W skrócie tzw. grid layout pozwala nam dzielić przestrzeń strony internetowej w sposób podobny do tego jaki oferują tabele, ale będąc częścią naszego arkusza stylów staje się elementem bardziej dynamicznym i elastycznym niż html’owa tabela. Nie dość, że możemy „szatkować” naszą stronę do woli tworząc skomplikowane układy kontenerów dla treści to jeszcze wszystko to dzieje się z poziomu pliku css!
Mając takie narzędzie pod ręką nic nie stoi na przeszkodzie by rozbudowywać je o inne techniki i narzędzia (np. przez dodanie @media możemy tworzyć responsywne layouty stron www). Bez wątpienia potęga drzemiąca w grid layout jest niesamowita.
Dodatkowo elastyczność grid’u wynika też z jego własnych właściwości. Podział rozmiarów dzieje się dynamicznie i dostosowuje się do dostępnej przestrzeni.
Samo wprowadzenie grid layout jest banalnie proste. W naszym akruszu stylów musimy stworzyć element, który stanie sie funadamentem układu strony i dopisać:
1 | display: grid; |
lub:
1 | display: inline-grid; |
Proste? Tak. Dalej sprawy są bardziej skomplikowane.
Przykład kodu (W3C)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <style> #grid { display: grid; /* Two columns: the first sized to content, the second receives the remaining space, */ /* but is never smaller than the minimum size of the board or the game controls, which */ /* occupy this column. */ grid-columns: auto minmax(min-content, 1fr); /* Three rows: the first and last sized to content, the middle row receives the */ /* remaining space, but is never smaller than the minimum height of the board or stats */ /* areas. */ grid-rows: auto minmax(min-content, 1fr) auto } /* Each part of the game is positioned between grid lines by referencing the starting grid */ /* line and then specifying, if more than one, the number of rows or columns spanned to */ /* determine the ending grid line, which establishes bounds for the part. */ #title { grid-column: 1; grid-row: 1 } #score { grid-column: 1; grid-row: 3 } #stats { grid-column: 1; grid-row: 2; justify-self: start } #board { grid-column: 2; grid-row: 1; grid-row-span: 2 } #controls { grid-column: 2; grid-row: 3; align-self: center } </style> <div id="grid"> <div id="title">Game Title</div> <div id="score">Score</div> <div id="stats">Stats</div> <div id="board">Board</div> <div id="controls">Controls</div> </div> |
Jak widać początek jest dość prosty, czyli deklarujemy „display:grid” dla wybranego elementu. Dalsza część kodu jest pewnie mniej zrozumiała, ale wynika to głównie z tego że mamy do czynienia z czymś nowym. Powyższy fragment kodu pochodzi z dokumentu W3C i jest dostosowany do przykładu w nim podanego, ale dla nas jest istotny tylko po to aby opisać kilka podstawowych dostępnych opcji.
Grid element
To jakby kontener dla naszego layoutu. Odwołując się do powyższego, przykładowego kodu grid elementem będzie id grid, któremu nadaliśmy właściwośc „display:grid”, która to sprawia, iż jego dzieci stają się grid items i mogą być pozycjonowane wewnątrz swojego rodzica. W założeniu przypomina to trochę (ale nie dosłownie) absolutne pozycjonowanie elementów wewnątrz innego elementu pozycjonowanego absolutnie.
Grid tracks
Tutaj mamy do czynienia z elementami przypominającymi kolumny i rzędy tabel. Określając je tak na prawdę podajemy po prostu wielkości. ich deklaracja następuja w tzw. grid element.
1 2 3 4 5 | #grid { display: grid; grid-definition-columns: 150px 1fr; /* two columns */ grid-definition-rows: 50px 1fr 50px /* three rows */ } |
Grid lines
To pionowe i poziome linie istniejące między kolumnami i rzędami. Grid items wykorzystują je do ustalenia swojej pozycji i dostępnej przestrzeni. Dzieję się to przez odniesienie do właściwości grid-row i grid-column.
1 2 3 4 5 6 7 | #grid { display: grid; grid-definition-columns: 150px 1fr; grid-definition-rows: 50px 1fr 50px } #item1 { grid-column: 2; grid-row: 1 4 } |
Grid areas
Mamy tutaj do czynienia z przestrzenią wykorzystywaną do wyświetlenia minimum jednego grid item. Mogą one być określane wprost przy użyciu właściwości grid-template lub poniekąd pośrednio przez deklarowanie pewnego elementu przestrzeni layoutu za pomocą grid-row i grid-column okreslonego w grid item.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* using the template syntax */ #grid { display: grid; grid-template: ". a" "b a" ". a"; grid-definition-columns: 150px 1fr; grid-definition-rows: 50px 1fr 50px } #item1 { grid-area: "a" } #item2 { grid-area: "b" } #item3 { grid-area: "b" } /* Align items 2 and 3 at different points in the Grid Area "b". */ /* By default, Grid Items are stretched to fit their Grid Area */ /* and these items would layer one over the other. */ #item2 { align-self: head } #item3 { justify-self: end; align-self: foot } |
Grid items
Jak już wspomnieliśmy wcześniej grid items do dzieci grid element. Tworzą one jakby własny poziom layoutu umożliwiający manipulacje z poziomu arkusza stylów. Przykład poniżej:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <div style="display:grid"> <!-- grid item: block child --> <div id="item1">block</div> <!-- grid item: floated element; floating is ignored --> <div id="item2" style="float: left;">float</div> <!-- grid item: anonymous block box around inline content --> anonymous item 3 <!-- grid item: inline child --> <span> item 4 <!-- grid items do not split around blocks --> <div id=not-an-item>item 4</div> item 4 </span> </div> |
Wyraźnie mamy tutaj do czynienia z pisaniem zupelnie nowej historii css’a. Przyszłość tworzy się na naszych oczach i chyba warto zapoznać sie z całością dokuemntu W3C CSS Grid Layout Editor’s Draft, 2 August 2012, na podstawie którego napisano powyższy artykuł i z którego pochodzą przykłady kodu.
Co oznacza 1fr, bo mogę się domyślać ale niestety nic nie łapie bez tego ;(
Cytując Editor Draft:
„Fraction values are new units applicable
to the ‘grid-definition-rows’ and ‘grid-definition-columns’ properties:
fr
Fraction of available space.
The distribution of fractional space occurs after all ‘length’ or content-based row
and column sizes have reached their maximum. The total size of the rows
or columns is then subtracted from the available space and the remainder
is divided proportionately among the fractional rows and columns.”