W zamierzchłych czasach sieci, gdy style CSS nie były jeszcze tak rozwinięte jak dzisiaj, rozplanowanie elementów na stronie realizowano się przy pomocy tabelek. Nie był to jednak najlepszy sposób, gdyż nie spełniał podstawowych zasad semantyki. Tabele zostały stworzone z myślą o prezentacji zbioru danych o powtarzającym się charakterze. Na szczęście style CSS wprowadziły nowe sposoby układania elementów na stronie, bez potrzeby używania w niewłaściwy sposób znaczników tabeli. Paradoksalnie właściwość position (pozycja) nie nadawała się zbytnio do ustalania głównego układu elementów na stronie, ponieważ wymagała, aby rozmiary bloków były z góry znane. W praktyce z taką sytuacją rzadko mamy do czynienia, gdyż nie jesteśmy w stanie od razu dokładnie przewidzieć, ile tekstu będą zawierać artykuły, opublikowane w serwisie.
Rozwiązaniem miało być płynne ustalanie pozycji przy pomocy właściwości float [zobacz: Szablon strony na DIV-ach]. I rzeczywiście w większości typowych zastosowań taki sposób był zupełnie wystarczający. Niestety w pewnych szczególnych przypadkach miał podobne ograniczenia jak pozycja absolutna. Bardzo trudno było zrealizować, zdawać by się mogło, tak trywialne sposoby układania elementów, jak wyśrodkowanie w pionie czy ustawienie kilku kolumn obok siebie przy zachowaniu takiej samej ich wysokości. W niektórych sytuacjach cierpiała na tym dostępność serwisu. Syntezatory mowy, stosowane w przeglądarkach używanych przez osoby niewidome, odczytują treść strony w kolejności jej występowanie w kodzie źródłowym HTML, a nie wizualnego ułożenia bloków na ekranie. Dlatego często korzystniej jest, aby najpierw w kodzie umieścić treść artykułu, a dopiero po niej rozbudowane menu nawigacyjne. Niestety w takiej sytuacji nie można było stworzyć prawdziwie elastycznego układu strony, z kolumną menu po lewej stronie, a treścią artykułu zajmującą całą wolną przestrzeń po prawej.
Na szczęście CSS3 rozwiązuje ten problem. Nie trzeba już stosować tabelek, pozycji absolutnych ani trików z płynnym układaniem elementów. Dzięki koncepcji układu elastycznego (ang. flexible box layout) dostajemy zaawansowane możliwości rozplanowania bloków na stronie, przy jednoczesnym automatycznym dopasowywaniu się całego układu, tak aby dokładnie spełniał nasze oczekiwania, bez względu na ilość treści w poszczególnych blokach na stronie.
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { display: flex }
selektor { display: inline-flex }
Tak tworzy się tzw. kontener elastyczny (ang. flex container), w którym dzieci układane są elastycznie. Sam kontener nie jest układany elastycznie na stronie, a jedynie jego dzieci. Wstawienie takiego kontenera przełącza tryb wyświetlania elementów w nim zawartych na układ elastyczny.
Aby jakiekolwiek własności, opisane dalej w tym rozdziale, dały widoczny efekt, konieczne jest dodanie powyższego stylu do elementu, który ma wyznaczać układ elastyczny.
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { flex-direction: kierunek }
Polecenie pozwala sterować ułożeniem bloków w sposób podobny do wyrazów w tekście akapitu. Wyrazom jednak nie możemy nadawać rozmiarów, a blokom w układzie elastycznym - tak.
selektor { flex-wrap: zawijanie }
Polecenie pozwala sterować ułożeniem wierszy bloków w sposób podobny do linii w tekście akapitu.
selektor { flex-flow: wartości atrybutów }
Polecenie to pozwala od razu podać kierunek i zawijanie elementów w układzie elastycznym.
Przykład:
"flex-flow: row nowrap
" - zwróć uwagę, że wszystkie elementy są identycznej wysokości:
"flex-flow: row wrap
" - zwróć uwagę, że wysokość bloków dopasowuje się automatycznie w każdym osobnym wierszu układu:
flex-flow: row-reverse nowrap
flex-flow: row-reverse wrap-reverse
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { order: kolejność }
Możliwość swobodnego ustalania kolejności wyświetlania się elementów to następna duża zaleta układu elastycznego. Przy wstawiania znaczników HTML do kodu źródłowego już nie musimy się martwić, aby były one osadzone w kolejności odpowiedniej do ich poprawnego wyświetlenia - zgodnie z zaprojektowaną grafiką serwisu.
Dzięki temu możemy tworzyć bardziej dostępne dokumenty. Przykładowo dla osoby niewidomej, która używa przeglądarki z syntezatorem mowy, prawdopodobnie korzystniej będzie, jeśli zapoznając się z katalogiem produktów w sklepie internetowym, najpierw usłyszy informacje o nazwie produktu, a potem jego opis. Zdjęcie jest w tym przypadku zupełnie nieważne, dlatego najlepiej jest wstawić je na końcu. Jednak dla użytkowników z dobrym wzrokiem właśnie zdjęcie może okazać się najważniejsze. Umieszczając je w kontenerze elastycznym, a następnie określając dla niego styl "order: -1
", wyświetlimy go na początku, podczas gdy syntezator mowy trafi na niego dopiero na końcu. W ten sposób potrzeby obu grup użytkowników zostaną spełnione.
Przykład:
Poniżej przykład fragmentu szablonu strony, który spełnia założenia dostępności - treść znajduje się w kodzie źródłowym przed kolumną menu. Mimo tego szerokość automatycznie dopasowuje się do okna przeglądarki. Dodatkowo warto zwrócić uwagę, że wysokość obu kolumn jest identyczna. Uzyskanie takiego efektu w tradycyjny sposób byłoby bardzo trudne i najczęściej wymagało pójścia na pewne kompromisy.
<div id="top"> <div id="TRESC">Treść strony...</div> <div id="MENU">Menu nawigacyjne</div> </div>
#top { display: flex; } #MENU { width: 150px; min-width: 150px; order: -1; }
[porównaj: Płynny szablon]
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { flex-grow: rozciągnięcie }
Może się zdarzyć, że w jednym wierszu kontenera elastycznego mogłoby się zmieścić więcej elementów niż mamy zapewnionych. Wtedy zwykle z prawej strony pozostaje wolna przestrzeń. Możemy jednak sprawić, aby w takiej sytuacji szerokość elementów elastycznie dopasowała się w taki sposób, aby wypełniły całą dostępną przestrzeń kontenera. Jeżeli chcemy, aby wszystkie elementy zostały rozciągnięte równomiernie, wystarczy każdemu przypisać styl "flex-grow: 1
". Możemy też zadecydować, aby np. jeden z nich rozszerzył się dwa razy bardziej niż inne - przypisujemy mu wartość "flex-grow: 2
". Istnieje również możliwość ustalenia, aby tylko jeden element wypełnił całą pozostałą wolną przestrzeń w kontenerze. Wtedy tylko jemu nadajemy styl "flex-grow: 1
".
selektor { flex-shrink: ściśnięcie }
Jeżeli kontener elastyczny jest zbyt wąski, jego dzieci są ściskane. Zwykle odbywa się to poprzez przełamanie do nowej linii tekstu, który zawiera się w tych blokach.
selektor { flex-basis: baza }
Baza określa początkowy rozmiar elementu w kontenerze, zanim wolna przestrzeń zostanie rozłożona pomiędzy dzieci kontenera.
Wartość "0" (zero) spowoduje, że rozmiary elementów będą bezpośrednio proporcjonalne do przypisanych im wartości flex-grow
(albo flex-shrink
- w przypadku ściśnięcia). Jeżeli wszystkie elementy kontenera będą miały przypisany styl "flex-grow: 1
", w efekcie mogą zostać rozciągnięte do dokładnie takiego samego rozmiaru.
Wartość "auto" (domyślnie) spowoduje, że rozmiary absolutne poszczególnych elementów mogą nie być równe, ponieważ wolna przestrzeń rozłoży się proporcjonalnie tylko po bokach wewnątrz elementów.
Powyższy diagram przedstawia różnice między "absolutną" (baza zerowa) a "relatywną" (baza zależna od zawartości elementów) elastycznością. Kolejne elementy w poszczególnych kontenerach elastycznych mają przypisaną wartość flex-grow
odpowiednio: 1, 1, 2.
Źródło: CSS Flexible Box Layout Module
selektor { flex: wartości atrybutów }
Polecenie to pozwala od razu podać rozciągnięcie, ściśnięcie i bazę elementów w układzie elastycznym. Każda z wartości jest opcjonalna, przy czym jeśli chcemy podać flex-shrink
, należy obowiązkowo poprzedzić ją wartością flex-grow
. Nie ma możliwości określenia w ten sposób samego ściśnięcia bez ustalania rozciągnięcia. Ponadto jeśli chcemy określić zerową długość flex-basis
, trzeba koniecznie dopisać do niej jednostkę. Choć normalnie jednostka przy wartości zero nie jest wymagana, tutaj zapobiega omyłkowemu uznaniu długości bazy za rozciągnięcie lub ściśnięcie. Jednostkę można pominąć tylko, kiedy w deklaracji występują wszystkie trzy wartości.
Jako wartości atrybutów można wpisać również samo słowo kluczowe "none", co odpowiada: "0 0 auto
" ("flex-grow: 0; flex-shrink: 0; flex-basis: auto
"). Warto zauważyć, że domyślna wartość tych atrybutów jest inna - "0 1 auto
".
Z uwagi na fakt, że składnia tego polecenia przewiduje najczęstsze przypadki użycia, zaleca się stosować zawsze atrybuty mieszane zamiast osobnych poleceń.
Przykład:
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { margin-top: auto } selektor { margin-right: auto } selektor { margin-bottom: auto } selektor { margin-left: auto } selektor { margin: auto }
Ustawiając wybrany margines na wartość automatyczną sprawimy, że wypełni on wolną przestrzeń pozostałą w kontenerze. Dzięki temu w bardzo prosty sposób możemy ustawić kilka bloków w jednej linii - część przy lewej krawędzi, a niektóre przy prawej.
Przykład:
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { justify-content: justowanie }
Polecenie steruje justowaniem elementów kontenera elastycznego, gdy jest on zbyt duży, aby został wypełniony w całości. Działa analogicznie jak justowanie tekstu, ale może operować na blokach.
Przykład:
justify-content: flex-start
justify-content: flex-end
justify-content: center
justify-content: space-between
justify-content: space-around
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { align-items: wyrównanie }
Polecenie steruje wyrównaniem jednego wiersza wewnątrz kontenera elastycznego, kiedy mają one różną wysokość.
Przykład:
align-items: flex-start
align-items: flex-end
"align-items: center
" - ten sposób pozwala wyśrodkować w pionie element, nawet jeżeli z góry nie wiemy, ile treści będzie się w nim znajdować:
align-items: baseline
align-items: stretch
selektor { align-self: wyrównanie }
Wyrównanie indywidualne pozwala ustawić w różny sposób każdy z elementów kontenera elastycznego. Jeżeli jednak wszystkie mają być wyrównane tak samo, korzystniej będzie zrobić to dla nich wspólnie.
(CSS 3 - interpretuje Internet Explorer 10, Firefox, Opera 12, Chrome)
selektor { align-content: wyrównanie }
Polecenie steruje wyrównaniem wielu wierszy wewnątrz kontenera elastycznego, kiedy ich sumaryczna wysokość jest za mała, aby wypełnić całą dostępną przestrzeń.
Przykład:
align-content: flex-start
align-content: flex-end
align-content: center
align-content: space-between
align-content: space-around
align-content: stretch