Jak ustawić bloki strony obok siebie
Prawie każdy arkusz INF.03 każe zbudować stronę z tych samych klocków: baner na górze, czasem menu, pod spodem dwa lub trzy panele obok siebie i stopka na dole. Arkusz podaje szerokości i wysokości, a obrazek pokazuje, gdzie co ma stać. Ustawienie paneli obok siebie należy do ciebie. Najczęściej robi się to przez float albo display: flex. Kurs uczy obu, a potem pokazuje display: grid i position.
headerbanernavmenuasidepanel bocznymaintreśćfooterstopka
Te same kolory mają bloki we wszystkich przykładach i ćwiczeniach, więc od razu widać, który jest który.
Ten sam układ dwiema technikami
aside {
float: left;
width: 25%;
height: 120px;
}
main {
float: left;
width: 75%;
height: 120px;
}
footer {
clear: both;
}#srodek {
display: flex;
min-height: 120px;
}
aside {
width: 25%;
}
main {
flex: 1;
}
/* stopka nie potrzebuje niczego */Jak korzystać z kursu
- Lekcje idą po kolei i każda korzysta z poprzednich. Zaczynasz od znaczników, z których składa się strona. Części o float, flex i grid kończą się tym samym pełnym układem, za każdym razem zrobionym inaczej. Na koniec
position, czyli nakładanie i przyklejanie elementów. - W lekcjach są dema z przełącznikami. Zaznacz pole i zobacz, co jedna właściwość zmienia na stronie.
- Każda lekcja ma ćwiczenie. Piszesz CSS, podgląd odświeża się w trakcie pisania, a przycisk „Sprawdź” mierzy położenie bloków na stronie o szerokości 800px.
- Postęp i twoje szkice zapisują się w tej przeglądarce.
Znaczniki układu: z czego składa się strona
Zanim cokolwiek ustawisz, strona musi być podzielona na bloki. Dawniej każdy blok był znacznikiem <div> z identyfikatorem: <div id="baner">, <div id="stopka">. HTML5 dodał znaczniki, których nazwa mówi, czym blok jest. Nazywa się je semantycznymi, czyli niosącymi znaczenie.
Wszystkie znaczniki z tej lekcji zachowują się w przeglądarce identycznie: są blokami na całą szerokość, bez tła, bez ramki i bez marginesów. <header> nie ustawia się sam na górze, a <aside> nie staje sam z boku. Znacznik mówi, czym blok jest. O tym, gdzie stoi i jak wygląda, decyduje CSS i kolejność w kodzie.
<header>: baner, nagłówek
Do czego służy: część wprowadzająca. Na poziomie strony to baner z tytułem, logo i ewentualnie hasłem.
Kiedy używać: gdy arkusz mówi „baner” albo „nagłówek strony”. W środku zwykle jest <h1> z tytułem, czasem obraz logo.
Uwaga na pomyłki: <header> to nie to samo co <head> (niewidoczna część dokumentu z tytułem karty i podłączeniem stylów) ani <h1> (sam tekst nagłówka). <header> jest blokiem w <body>, w którym <h1> leży.
<nav>: menu
Do czego służy: blok z odnośnikami, którymi przechodzi się po witrynie.
Kiedy używać: dla głównego menu strony, czyli grupy odnośników do podstron albo do sekcji tej samej strony. Odnośniki mogą leżeć w nim luzem albo w liście <ul>.
Kiedy nie: pojedynczy odnośnik w tekście albo link „pobierz plik” w stopce nie potrzebują <nav>. To znacznik na nawigację, a nie na każde <a>.
<main>: główna treść
Do czego służy: to, po co użytkownik otworzył tę konkretną stronę. Wszystko, co powtarza się na każdej podstronie (baner, menu, stopka), zostaje poza nim.
Kiedy używać: raz na stronie, dla bloku z właściwą treścią. Gdy strona ma panel lewy i prawy, <main> może być kontenerem na oba albo tym z nich, który zawiera treść główną.
Zasady: tylko jeden widoczny <main> w dokumencie. Nie wkłada się go do <header>, <nav>, <aside> ani <footer>.
<section>: część treści
Do czego służy: fragment strony na jeden temat, na przykład „Oferta”, „Cennik”, „Kontakt”.
Kiedy używać: gdy blok ma własny temat i zwykle własny nagłówek <h2> lub <h3>. W arkuszach to najczęstszy znacznik dla paneli: „panel lewy”, „panel prawy”, „blok główny”.
Kiedy nie: gdy blok jest potrzebny tylko po to, żeby coś ostylować albo zgrupować. Wtedy właściwy jest <div>. Prosty test: jeśli nie umiesz nadać blokowi tytułu, to nie jest sekcja.
<aside>: treść poboczna
Do czego służy: dodatek do głównej treści. Strona bez niego dalej ma sens.
Kiedy używać: panel boczny z godzinami otwarcia, listą odnośników do innych stron, reklamą, ciekawostką, formularzem logowania obok artykułu.
Uwaga: nazwa znaczy „na marginesie” w sensie treści, a nie położenia. <aside> może leżeć pod treścią albo nad nią. Z boku stanie dopiero wtedy, gdy ustawisz go tam w CSS.
<footer>: stopka
Do czego służy: informacje zamykające: autor, rok, kontakt, odnośniki dodatkowe.
Kiedy używać: dla stopki strony. W arkuszach to blok z napisem „Stronę wykonał:” i numerem zdającego.
Uwaga: stopka jest ostatnim blokiem w kodzie, ale to, czy dotyka dołu okna, zależy już od CSS.
<div>: blok bez znaczenia
Do czego służy: do grupowania. Nie mówi nic o tym, co ma w środku.
Kiedy używać: gdy potrzebujesz pudełka wyłącznie dla CSS albo JavaScript. Najczęstszy przypadek w tym kursie to kontener, który obejmuje panele, żeby dało się na nim ustawić display: flex. Inne: ramka galerii, wiersz formularza, okno z powiększonym obrazem.
Kiedy nie: gdy istnieje znacznik, który opisuje ten blok. Baner jako <div id="baner"> zadziała tak samo, ale w arkuszu wymagającym znaczników semantycznych stracisz punkt.
div czy section: jak rozstrzygnąć
Te dwa znaczniki myli się najczęściej, bo w przeglądarce wyglądają i działają tak samo. Różnią się tylko tym, co mówią o zawartości. <section> twierdzi: „to jest osobna część treści na jakiś temat”. <div> nie twierdzi nic.
Zadaj sobie po kolei trzy pytania. Pierwsza odpowiedź „tak” kończy sprawę.
- Czy istnieje dokładniejszy znacznik? Baner, menu, główna treść, dodatek z boku i stopka mają własne znaczniki. Wtedy ani
div, anisection. - Czy blok ma własny temat i dałoby się go zatytułować? „Oferta”, „Cennik”, „Galeria”, „Kontakt”, „Panel lewy z listą kursów”. Wtedy
<section>, najlepiej z nagłówkiem<h2>lub<h3>w środku. - Czy blok istnieje tylko po to, żeby coś ustawić, ostylować albo złapać w skrypcie? Wtedy
<div>.
<section> | <div> | |
|---|---|---|
| Co oznacza | Część treści na jeden temat. | Nic. Samo pudełko. |
| Po co go dodajesz | Bo treść dzieli się na części. | Bo potrzebuje tego CSS albo JavaScript. |
| Nagłówek w środku | Prawie zawsze. | Zwykle nie ma. |
| Gdybyś usunął znacznik, a zostawił zawartość | Strona straciłaby podział na części. | Zmieniłby się tylko wygląd. |
| Czy trafiłby do spisu treści strony | Tak. | Nie. |
| Typowa nazwa w arkuszu | panel lewy, panel prawy, blok główny, sekcja | kontener, blok na panele, ramka, wiersz |
Przykłady, w których właściwy jest section
- Panel lewy z nagłówkiem „Nasze kursy” i listą kursów.
- Panel prawy z nagłówkiem „Zapisz się” i formularzem.
- Kolejne części długiej strony: „O nas”, „Cennik”, „Opinie”.
- Blok z tabelą wyników i tytułem nad nią.
Przykłady, w których właściwy jest div
- Kontener obejmujący dwa panele, żeby ustawić na nim
display: flexalbo zatrzymać zapadanie się rodzica. - Blok o stałej szerokości z
margin: 0 auto, który trzyma całą stronę na środku okna. - Ramka wokół jednego zdjęcia z podpisem w galerii, kafelek produktu, wiersz formularza z etykietą i polem.
- Element, do którego skrypt wstawia wynik albo który skrypt pokazuje i ukrywa.
Oba znaczniki często występują razem i wtedy każdy robi swoje. <div> jest pudełkiem dla układu, a <section> w środku dzielą treść:
<div id="panele"> <!-- tylko po to, żeby panele stanęły obok siebie -->
<section id="lewy"> <!-- część treści: oferta -->
<h2>Nasze kursy</h2>
<ul>...</ul>
</section>
<section id="prawy"> <!-- część treści: zapisy -->
<h2>Zapisz się</h2>
<form>
<div class="wiersz"> <!-- tylko po to, żeby etykieta i pole były w jednej linii -->
<label for="imie">Imię:</label>
<input type="text" id="imie">
</div>
</form>
</section>
</div>
Typowe błędy
- Section jako pudełko do stylowania.
<section class="kontener">wokół wszystkiego, bez tematu i bez nagłówka. To powinien być<div>. - Div wszędzie. Strona z samych
<div id="...">działa, ale nie spełnia wymogu znaczników semantycznych. - Section w miejscu dokładniejszego znacznika. Stopka jako
<section id="stopka">zamiast<footer>, menu jako<section>zamiast<nav>. - Section wokół każdego akapitu. Akapit to
<p>. Sekcja grupuje nagłówek z tym, co do niego należy.
<section>. Gdy pisze „blok” albo „kontener”, wystarczy <div>. Dodatkowy <div>, którego potrzebujesz do ustawienia paneli, jest dozwolony zawsze, bo niczego w znaczeniu strony nie zmienia. W razie wątpliwości przy panelu z nagłówkiem wybierz <section>, a przy pudełku bez własnej treści <div>.Który znacznik wybrać
| Arkusz albo obraz mówi | Znacznik | Ile razy na stronie |
|---|---|---|
| baner, nagłówek strony | <header> | zwykle raz |
| menu, panel z odnośnikami do podstron | <nav> | zwykle raz |
| blok główny, treść strony | <main> | dokładnie raz |
| panel lewy, panel prawy, blok z własnym tematem | <section> | dowolnie |
| panel boczny z dodatkami | <aside> | dowolnie |
| stopka | <footer> | zwykle raz |
| nic z powyższych, pudełko dla CSS | <div> | dowolnie |
Jest jeszcze <article>: samodzielna całość, którą można by wyjąć ze strony i opublikować gdzie indziej, na przykład wpis na blogu, ogłoszenie, opinia klienta. W arkuszach pojawia się rzadko.
Cały szkielet strony
<body>
<header>
<h1>Sklep rowerowy</h1>
</header>
<nav>
<a href="index.html">Start</a>
<a href="oferta.html">Oferta</a>
</nav>
<div id="srodek">
<aside>Godziny otwarcia: 9–17</aside>
<main>
<section>
<h2>Nowe modele</h2>
<p>Rowery górskie i miejskie.</p>
</section>
</main>
</div>
<footer>Stronę wykonał: 00000000000</footer>
</body>
Kolejność znaczników w kodzie jest taka jak kolejność bloków na obrazie, czytana od góry do dołu i od lewej do prawej. <div id="srodek"> nic nie znaczy, jest tu tylko wspólnym rodzicem dla panelu i treści.
<div> z identyfikatorem jest w porządku.Bloki i normalny przepływ
Znaczniki header, nav, main, section, aside, footer i div to elementy blokowe. Bez żadnego CSS każdy z nich zajmuje całą szerokość rodzica i staje pod poprzednim. To się nazywa normalny przepływ dokumentu. Wysokość bloku wynika z tego, co ma w środku.
<header>Baner</header> <main>Treść</main> <footer>Stopka</footer>
Trzy właściwości wystarczą, żeby zmienić rozmiar bloku i jego miejsce w poziomie:
| Właściwość | Co robi |
|---|---|
width | Szerokość. W pikselach albo w procentach szerokości rodzica. |
height | Wysokość. Arkusze podają ją zwykle w pikselach. |
margin: 0 auto | Wyśrodkowuje w poziomie blok, który ma ustawioną szerokość. Wolne miejsce dzieli się po równo na lewo i prawo. |
Zwróć uwagę na dwie rzeczy. Blok zwężony do 60% dalej stoi sam w swoim wierszu, miejsce obok zostaje puste. Samo width nigdy nie postawi dwóch bloków obok siebie. Druga rzecz: przeglądarka sama dodaje do body margines 8px, stąd biała ramka dookoła strony. Usuwa ją body { margin: 0; }.
body { margin: 0; }.Dwa panele obok siebie
float: left wyjmuje blok z normalnego przepływu i dosuwa go do lewej krawędzi rodzica. Kolejny blok z float: left staje zaraz po jego prawej stronie. Tak powstają panele.
#lewy {
float: left;
width: 30%;
height: 300px;
}
#prawy {
float: left;
width: 70%;
height: 300px;
}
Trzy zasady, które zawsze obowiązują:
- Pływający blok kurczy się do szerokości swojej zawartości, więc każdy panel musi mieć ustawione
width. - Szerokości w jednym rzędzie nie mogą razem przekroczyć 100%. Jeśli przekroczą, ostatni panel spada do następnego wiersza.
- Float dostają wszystkie panele z rzędu. Gdy dostanie go tylko lewy, prawy blok wsuwa się pod niego, a jego tekst opływa lewy panel.
Zaznacz najpierw tylko pierwsze pole. Lewy panel dalej jest po lewej, ale prawy zaczyna się teraz od lewej krawędzi strony i chowa się częściowo pod lewym. Dopiero drugie pole ustawia oba panele w jednym rzędzie.
Stopka i clear
Pływające panele nie zajmują miejsca w normalnym przepływie. Dla stopki, która jest zwykłym blokiem, wyglądają tak, jakby ich nie było, więc stopka zaczyna się tuż pod banerem i wchodzi pod panele. Widać tylko jej tekst, który opływa panele tam, gdzie znajdzie miejsce.
clear: both każe blokowi zacząć się poniżej wszystkich pływających elementów, które stoją przed nim.
footer {
clear: both;
}
Panele w demie mają różną wysokość. Bez clear stopka wciska się w wolne miejsce pod niższym panelem. Z clear: both zaczyna się pod wyższym.
| Wartość | Blok schodzi pod elementy z |
|---|---|
clear: left | float: left |
clear: right | float: right |
clear: both | jednym i drugim. Używaj tej wartości, nie trzeba się zastanawiać. |
clear: both. Najczęściej jest to stopka.Padding, ramka i box-sizing
Panele 30% i 70% mieszczą się w rzędzie na styk. Wystarczy dodać im padding albo border, żeby prawy panel spadł pod lewy. Powód: domyślnie width oznacza szerokość samej zawartości, a padding i ramka są doliczane na zewnątrz.
/* strona ma 800px szerokości */
#lewy { width: 30%; padding: 20px; } /* 240 + 20 + 20 = 280px */
#prawy { width: 70%; padding: 20px; } /* 560 + 20 + 20 = 600px */
/* razem 880px, czyli o 80px za dużo */
box-sizing: border-box zmienia sposób liczenia. Od teraz width to szerokość całego pudełka razem z paddingiem i ramką. Tę regułę daje się wszystkim elementom naraz, selektorem gwiazdki:
* {
box-sizing: border-box;
}
Margines nie wchodzi do width w żadnym trybie. Jeśli panele mają mieć odstęp od siebie, odejmij go od szerokości, na przykład 30% i 68% z margin-left: 2%.
* { box-sizing: border-box; } na samej górze arkusza stylów.Rodzic, który się zapada
Często panele są zamknięte we wspólnym bloku, na przykład <div id="kontener"> z tłem albo ramką. Wysokość bloku liczy się z zawartości, która jest w normalnym przepływie. Jeśli wszystkie dzieci pływają, to rodzic nie ma z czego jej policzyć i dostaje wysokość 0. Tło znika, ramka zamyka się w cienką linię, a panele wystają poza nią.
Są trzy sposoby, żeby rodzic objął swoje pływające dzieci. Każdy dopisuje się do rodzica:
| Sposób | Uwagi |
|---|---|
overflow: auto | Najkrótszy i najczęściej spotykany w rozwiązaniach arkuszy. Jeśli zawartość wyjdzie poza ustawioną wysokość, pojawi się pasek przewijania. |
display: flow-root | Właściwość stworzona dokładnie do tego. Nie ma skutków ubocznych. |
| clearfix | Stary sposób, który zobaczysz w cudzym kodzie. Dopisuje za dziećmi pusty element z clear: both. |
/* clearfix */
#kontener::after {
content: "";
display: block;
clear: both;
}
body, a stopka ma clear: both.Trzy kolumny i float: right
Trzy panele robi się tak samo jak dwa: każdy dostaje float: left i szerokość, a suma nie przekracza 100%. Kolejność na stronie jest taka jak kolejność w HTML.
float: right dosuwa blok do prawej krawędzi rodzica. Przydaje się, gdy panel ma być przyklejony do prawej strony, a szerokości nie sumują się do 100% i między panelami ma zostać przerwa.
#lewy { float: left; width: 25%; }
#srodek { float: left; width: 40%; }
#prawy { float: right; width: 25%; }
/* 10% wolnego miejsca zostaje między środkiem a prawym */
Dwa bloki z float: right ustawiają się od prawej w kolejności z HTML: pierwszy w kodzie stoi najdalej po prawej. Jeśli chcesz uniknąć odwróconej kolejności, używaj float: left dla wszystkich i float: right tylko dla jednego, ostatniego panelu.
img { float: right; } stawia obraz po prawej, a akapit układa się po jego lewej stronie. Takie polecenie też bywa w arkuszach.Cały układ na float
Masz już wszystko, czego trzeba do typowego układu z arkusza. Plan pracy jest zawsze ten sam:
- Na górze arkusza stylów:
* { box-sizing: border-box; }ibody { margin: 0; }. - Bloki na całą szerokość (baner, menu, stopka) dostają tylko wysokość. Szerokości nie ustawiasz, bo blok sam zajmuje 100%.
- Bloki, które stoją w jednym rzędzie, dostają
float: left, szerokość w procentach i wysokość. - Pierwszy blok pod rzędem paneli dostaje
clear: both.
<header>Baner</header> <nav>Menu</nav> <aside>Panel boczny</aside> <main>Treść główna</main> <footer>Stopka</footer>
Kolejność znaczników w HTML odpowiada kolejności na obrazie czytanej od góry do dołu, a w obrębie rzędu od lewej do prawej.
height. Arkusze zwykle ją podają.display: flex, czyli kontener i jego dzieci
We flexie właściwość ustawiasz na rodzicu, a nie na panelach. Blok z display: flex staje się kontenerem, a jego bezpośrednie dzieci ustawiają się w rzędzie od lewej do prawej.
<div id="kontener"> <aside>Panel boczny</aside> <main>Treść</main> </div> <footer>Stopka</footer>
#kontener {
display: flex;
}
aside { width: 30%; }
main { width: 70%; }
W porównaniu z float znikają trzy kłopoty:
- Kontener sam obejmuje swoje dzieci. Nic się nie zapada.
- Stopka pod kontenerem jest w normalnym przepływie i nie potrzebuje
clear. - Panele w rzędzie mają równą wysokość, taką jak najwyższy z nich. Odpowiada za to domyślne
align-items: stretch.
body razem z banerem i stopką, zamknij je w dodatkowym <div> albo <section>. Arkusz tego nie zabrania.Szerokości: width i flex: 1
Element w kontenerze flex może dostać szerokość na dwa sposoby. Pierwszy to zwykłe width, w procentach albo pikselach. Drugi to flex: 1, które znaczy: weź całe miejsce, jakie zostało po pozostałych elementach.
#kontener { display: flex; }
#lewy { width: 200px; } /* stała szerokość */
main { flex: 1; } /* reszta miejsca */
#prawy { width: 150px; } /* stała szerokość */
Jeśli flex ma kilka elementów, wolne miejsce dzieli się między nie w proporcji podanych liczb. Dwa elementy z flex: 1 dostają po połowie. Przy flex: 2 i flex: 1 pierwszy dostaje dwie trzecie, drugi jedną trzecią.
| Zapis | Znaczenie |
|---|---|
flex: 1 | Skrót. Element rośnie i wypełnia wolne miejsce. |
flex-grow: 1 | To samo zapisane dłuższą nazwą: element może rosnąć. |
flex-shrink: 0 | Element nie może się zwężać poniżej swojej szerokości, gdy brakuje miejsca. |
flex-basis: 200px | Szerokość początkowa, od której liczy się rośnięcie i kurczenie. Działa jak width. |
box-sizing: border-box nadal warto wpisać, żeby szerokości zgadzały się z arkuszem co do piksela.Wyrównanie: justify-content, align-items, gap
Kontener flex ma dwie osie. Oś główna biegnie w kierunku układania elementów, domyślnie poziomo. Oś poprzeczna jest do niej prostopadła, domyślnie pionowa. Każda ma swoją właściwość wyrównania i obie ustawia się na kontenerze.
| Właściwość | Oś | Najważniejsze wartości |
|---|---|---|
justify-content | główna (poziom) | flex-start, center, flex-end, space-between, space-around, space-evenly |
align-items | poprzeczna (pion) | stretch, flex-start, center, flex-end |
gap | obie | odstęp między elementami, np. 20px. Nie dodaje odstępu przy krawędziach kontenera. |
Dwa zastosowania, które warto zapamiętać:
/* element dokładnie na środku rodzica */
#rodzic {
display: flex;
justify-content: center;
align-items: center;
}
/* logo po lewej, menu po prawej, oba na środku wysokości */
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
justify-content rozdziela tylko wolne miejsce. Jeśli któryś element ma flex: 1, wolnego miejsca nie ma i ta właściwość nic nie zmienia.
ul zamienia się w poziome menu przez display: flex na ul. Punkty li stają w rzędzie, a gap ustawia odstępy między nimi. Dawniej robiło się to przez float: left na każdym li.Kierunek, zawijanie i kolejność
flex-direction ustawia kierunek osi głównej. Domyślne row układa elementy w rzędzie, column w kolumnie, jeden pod drugim. Po zmianie na column osie zamieniają się rolami: justify-content działa w pionie, a align-items w poziomie.
flex-wrap: wrap pozwala elementom przejść do następnego wiersza, gdy się nie mieszczą. Bez tego kontener ściska wszystkie w jednym rzędzie.
Właściwość order ustawia się na elemencie. Zmienia jego miejsce bez ruszania HTML. Domyślnie każdy element ma order: 0, a elementy z większą liczbą idą dalej.
Stopka przyklejona do dołu okna
Kolumna przydaje się do całej strony. Gdy treści jest mało, stopka zwykłej strony wisi w połowie okna. Żeby zawsze leżała na dole, body staje się kolumną o wysokości co najmniej całego okna, a main zabiera wolne miejsce:
body {
min-height: 100vh; /* 100vh = wysokość okna */
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
Cały układ na flex
Ten sam układ co w lekcji „Cały układ na float”. W HTML zmienia się jedno: panel boczny i treść są zamknięte we wspólnym bloku, który będzie kontenerem flex.
<header>Baner</header> <nav>Menu</nav> <div id="srodek"> <aside>Panel boczny</aside> <main>Treść główna</main> </div> <footer>Stopka</footer>
Plan pracy:
- Na górze:
* { box-sizing: border-box; }ibody { margin: 0; }. - Baner, menu i stopka dostają tylko wysokość.
- Kontener dostaje
display: flexi wysokość rzędu. Lepiejmin-heightniżheight, bo wtedy rząd urośnie, gdy treści będzie więcej. - Panele dostają szerokości. Jeden może mieć
flex: 1i wziąć resztę.
Wysokości paneli nie ustawiasz. Rozciągają się same do wysokości kontenera.
body z display: flex i flex-wrap: wrap. Baner, menu i stopka dostają wtedy width: 100%, więc każdy zajmuje cały wiersz, a panele 25% i 75% mieszczą się razem w jednym.display: grid, czyli kolumny i wiersze
Flex układa elementy w jednej linii: w rzędzie albo w kolumnie. Grid dzieli kontener na siatkę kolumn i wierszy jednocześnie, a dzieci wchodzą po kolei do jej komórek. Tak jak we flexie, właściwości siatki pisze się na rodzicu.
#kontener {
display: grid;
grid-template-columns: 200px 1fr 1fr; /* trzy kolumny */
gap: 20px;
}
grid-template-columns wymienia szerokości kolejnych kolumn. Ile wartości, tyle kolumn. Wierszy przybywa samych, gdy elementów jest więcej niż kolumn.
| Wartość | Znaczenie |
|---|---|
200px, 25% | Stała szerokość kolumny albo procent szerokości kontenera. |
1fr | Jedna część wolnego miejsca. 1fr 3fr dzieli kontener w proporcji 1 do 3. Odpowiednik flex: 1. |
repeat(3, 1fr) | Skrót: trzy razy 1fr, czyli trzy równe kolumny. |
auto | Tyle, ile potrzebuje zawartość. |
grid-template-rows działa tak samo dla wysokości wierszy. gap ustawia odstępy między komórkami. Dwie wartości oznaczają osobno odstęp między wierszami i między kolumnami.
Element na kilka komórek
Linie siatki są ponumerowane od 1. Trzy kolumny mają cztery linie pionowe: przed pierwszą kolumną, dwie w środku i za ostatnią. Właściwość grid-column na elemencie mówi, od której do której linii ma on sięgać.
#duzy { grid-column: 1 / 3; } /* od linii 1 do linii 3, czyli dwie kolumny */
#duzy { grid-column: span 2; } /* to samo: zajmij dwie kolumny */
#pas { grid-column: 1 / -1; } /* od pierwszej do ostatniej linii, cały wiersz */
grid-row robi to samo w pionie.
Cały układ na grid
W gridzie kontenerem może być samo body, bo siatka ma i kolumny, i wiersze. Nie trzeba dodatkowego bloku na panele, więc HTML jest taki sam jak w układzie na float.
Najczytelniejszy zapis to grid-template-areas. Każdy cudzysłów to jeden wiersz siatki, a słowa w nim to nazwy obszarów w kolejnych kolumnach. Nazwę powtórzoną w sąsiednich komórkach zajmuje jeden element rozciągnięty na nie wszystkie.
body {
display: grid;
grid-template-columns: 25% 75%;
grid-template-rows: 80px 40px 300px 50px;
grid-template-areas:
"baner baner"
"menu menu"
"bok tresc"
"stopka stopka";
}
header { grid-area: baner; }
nav { grid-area: menu; }
aside { grid-area: bok; }
main { grid-area: tresc; }
footer { grid-area: stopka; }
Nazwy obszarów wymyślasz samodzielnie. W grid-area pisze się je bez cudzysłowu. Każdy wiersz musi mieć tyle słów, ile jest kolumn, a obszar musi być prostokątem.
W demie zmienia się tylko grid-template-areas. HTML i reszta stylu zostają te same, a bloki zamieniają się miejscami. We float i flex taka zmiana wymagałaby przestawienia znaczników.
To samo bez nazw obszarów: bloki na całą szerokość dostają grid-column: 1 / -1, a panele same wchodzą do dwóch komórek jednego wiersza.
body { display: grid; grid-template-columns: 25% 75%; }
header, nav, footer { grid-column: 1 / -1; }
grid-template-rows albo zwyczajnie jako height na blokach.position: relative i absolute
Float, flex i grid rozkładają bloki tak, żeby nie wchodziły na siebie. position służy do czegoś innego: przesuwa pojedynczy element w wybrane miejsce, także na wierzch innych. Samo miejsce podają właściwości top, right, bottom i left, czyli odległości od odpowiednich krawędzi.
| Wartość | Co robi | Od czego liczy się top / left |
|---|---|---|
static | Domyślna. Element leży w normalnym przepływie, top i left nie działają. | nie dotyczy |
relative | Element zostaje w przepływie i trzyma swoje miejsce, ale rysuje się przesunięty. | od własnego zwykłego położenia |
absolute | Element wypada z przepływu. Reszta strony układa się tak, jakby go nie było. | od najbliższego przodka, który ma position inne niż static. Gdy takiego nie ma, od całej strony. |
Z ostatniego wiersza wynika najważniejszy wzorzec. Rodzic dostaje position: relative bez żadnych przesunięć, tylko po to, żeby stał się punktem odniesienia. Dziecko dostaje position: absolute i współrzędne liczone od krawędzi rodzica.
#karta {
position: relative; /* punkt odniesienia */
}
#znaczek {
position: absolute;
top: 10px; /* 10px od górnej krawędzi karty */
right: 10px; /* 10px od prawej krawędzi karty */
}
Wypróbuj po kolei. Ustaw znaczkowi absolute oraz top i right, a karcie zostaw wyłączone relative: znaczek ucieknie do rogu całej strony. Dopiero relative na karcie sprowadza go do jej rogu. Potem przełącz znaczek na relative: przesunie się względem miejsca, w którym stał w tekście.
Kiedy tego używać
- Etykieta „Nowość” albo cena w rogu zdjęcia, podpis na obrazie, przycisk × w rogu okna.
- Rozwijane podmenu, które ma się pojawić pod pozycją menu i nie rozpychać strony.
- Element na środku rodzica:
top: 50%; left: 50%; transform: translate(-50%, -50%);.
position: absolute nie wiedzą o sobie nawzajem, więc nachodzą na siebie, gdy tekstu przybędzie albo okno się zwęzi. Baner, panele i stopkę ustawiaj floatem, flexem albo gridem.fixed, sticky i z-index
Dwie pozostałe wartości position wiążą element z oknem przeglądarki, więc widać je dopiero przy przewijaniu.
| Wartość | Co robi | Typowe użycie |
|---|---|---|
fixed | Element wypada z przepływu i jest przypięty do okna. Przy przewijaniu stoi w miejscu. Współrzędne liczą się od krawędzi okna. | Przycisk „Do góry” w rogu, pasek z informacją o ciasteczkach, menu zawsze na górze. |
sticky | Element leży w przepływie jak zwykły blok. Gdy przy przewijaniu dojedzie do podanej odległości od krawędzi okna, zatrzymuje się tam. | Menu, które najpierw jest pod banerem, a potem przykleja się do góry okna. Nagłówek tabeli. |
nav {
position: sticky;
top: 0; /* bez tej wartości sticky nie działa */
}
#dogory {
position: fixed;
right: 20px;
bottom: 20px;
}
Przewiń stronę w ramce przy każdym ustawieniu. Zwróć uwagę na fixed: menu wypadło z przepływu, więc skurczyło się do szerokości tekstu, a treść podjechała pod nie. Stąd dwie poprawki, które zawsze idą w parze z przypiętym paskiem: width: 100% na pasku i margines albo padding u góry treści, równy wysokości paska. Przy sticky nie trzeba żadnej z nich.
z-index: co jest na wierzchu
Gdy elementy na siebie nachodzą, wyżej rysuje się ten, który jest później w kodzie. z-index zmienia tę kolejność: element z większą liczbą jest na wierzchu. Działa tylko na elementach, które mają position inne niż static.
nav {
position: sticky;
top: 0;
z-index: 10; /* menu nad wszystkim, co pod nie wjeżdża */
}
static to zwykły przepływ, relative przesuwa względem własnego miejsca, absolute ustawia względem pozycjonowanego przodka, fixed względem okna, a sticky zachowuje się jak zwykły blok do chwili, gdy przyklei się do krawędzi okna.Float, flex czy grid
| Pytanie | Float | Flex | Grid |
|---|---|---|---|
| Gdzie piszesz właściwość | Na każdym panelu. | Na rodzicu paneli. | Na rodzicu, zwykle na body. |
| Dodatkowy blok na panele | Niepotrzebny. | Potrzebny. | Niepotrzebny. |
| Blok pod panelami | Musi mieć clear: both. | Nic nie trzeba. | Nic nie trzeba. |
| Rodzic paneli | Zapada się, potrzebuje overflow: auto. | Obejmuje dzieci sam. | Obejmuje dzieci sam. |
| Równa wysokość paneli | Tylko przez tę samą wartość height. | Automatycznie. | Automatycznie. |
| Szerokości paneli | width na każdym. | width albo flex: 1. | grid-template-columns w jednym miejscu. |
| Suma szerokości ponad 100% | Ostatni panel spada niżej. | Panele się zwężają. | Siatka wychodzi poza kontener. |
| Wyśrodkowanie w pionie | Nie ma na to właściwości. | align-items: center | align-items: center |
| Odstępy między panelami | Marginesy odjęte od szerokości. | gap | gap |
| Najlepszy do | Obrazu opływanego tekstem, starszych arkuszy. | Jednego rzędu paneli, paska menu. | Siatki kafelków, całego układu strony. |
position nie należy do tego zestawienia, bo nie służy do rozkładania bloków strony. Sięgasz po nie, gdy element ma leżeć na innym (absolute w rodzicu z relative) albo trzymać się okna (fixed, sticky).
Gdy układ się rozjechał
| Objaw | Przyczyna | Poprawka |
|---|---|---|
| Panele stoją jeden pod drugim. | Brak float na panelach albo display: flex na rodzicu. | Dopisz jedno z nich. |
| Ostatni panel spadł pod pozostałe. | Szerokości z paddingiem, ramką i marginesem dają ponad 100%. | * { box-sizing: border-box; }, potem przelicz marginesy. |
| Stopka jest schowana pod panelami albo obok nich. | Panele pływają, a stopka nie ma clear. | footer { clear: both; } |
| Tło lub ramka rodzica zniknęły. | Rodzic ma same pływające dzieci i wysokość 0. | overflow: auto na rodzicu. |
display: flex nic nie zmienia. | Jest ustawione na panelu, a nie na jego rodzicu, albo panele nie są bezpośrednimi dziećmi kontenera. | Przenieś regułę na rodzica. |
| Biały pasek dookoła strony. | Domyślny margines body. | body { margin: 0; } |
margin: 0 auto nie środkuje. | Blok nie ma ustawionej szerokości albo pływa. | Dodaj width, usuń float. |
Element z absolute uciekł do rogu strony. | Żaden jego przodek nie ma ustawionego position. | position: relative na rodzicu. |
position: sticky nie przykleja. | Brak top. | Dopisz top: 0. |
| Przypięte menu zasłania początek treści. | fixed wyjmuje element z przepływu. | Margines u góry treści równy wysokości menu albo sticky zamiast fixed. |
z-index nic nie zmienia. | Element ma position: static. | Dodaj position: relative. |
| W gridzie wszystko jest w jednej kolumnie. | Brak grid-template-columns. | Podaj szerokości kolumn. |
justify-content nie działa. | Któryś element ma flex: 1 i zabrał całe wolne miejsce. | Usuń flex: 1 albo użyj gap. |
float i clear po prostu nie działają. W jednym arkuszu możesz za to użyć flexa do paneli i floata do obrazu, który ma opływać tekst.Quiz
Pytania w stylu części pisemnej egzaminu. Po kliknięciu odpowiedzi zobaczysz wyjaśnienie.
Ściąga
Początek każdego arkusza stylów
* { box-sizing: border-box; }
body { margin: 0; }
Float
| Co chcesz zrobić | Gdzie | Właściwości |
|---|---|---|
| Panele w jednym rzędzie | każdy panel | float: left + width |
| Panel przy prawej krawędzi | panel | float: right + width |
| Blok pod panelami | stopka | clear: both |
| Rodzic ma objąć panele | rodzic | overflow: auto albo display: flow-root |
| Tekst opływa obraz | obraz | float: left albo float: right |
| Blok na środku strony | blok | width + margin: 0 auto |
Flex: właściwości kontenera
| Właściwość | Wartości | Co ustawia |
|---|---|---|
display | flex | Dzieci stają w rzędzie. |
flex-direction | row, column, row-reverse, column-reverse | Kierunek osi głównej. |
flex-wrap | nowrap, wrap | Czy elementy mogą przejść do nowego wiersza. |
justify-content | flex-start, center, flex-end, space-between, space-around, space-evenly | Rozkład wzdłuż osi głównej. |
align-items | stretch, flex-start, center, flex-end | Wyrównanie w osi poprzecznej. |
gap | np. 20px | Odstęp między elementami. |
Flex: właściwości elementu
| Właściwość | Co ustawia |
|---|---|
width: 30% | Szerokość elementu. |
flex: 1 | Element bierze wolne miejsce. Kilka elementów dzieli je w proporcji liczb. |
flex-shrink: 0 | Element się nie zwęża. |
order: 1 | Przesuwa element za te z mniejszą liczbą. |
margin-left: auto | Odpycha element do prawej krawędzi kontenera. |
align-self: center | Wyrównanie w osi poprzecznej tylko dla tego elementu. |
Grid
| Właściwość | Gdzie | Co ustawia |
|---|---|---|
display: grid | kontener | Dzieci wchodzą do komórek siatki. |
grid-template-columns: 25% 1fr | kontener | Liczbę i szerokości kolumn. repeat(3, 1fr) to trzy równe. |
grid-template-rows: 80px 300px | kontener | Wysokości wierszy. |
grid-template-areas | kontener | Nazwane obszary, jeden cudzysłów na wiersz. |
gap: 20px | kontener | Odstępy między komórkami. |
grid-area: baner | element | Obszar, który element zajmuje. |
grid-column: 1 / -1 | element | Element na cały wiersz. span 2 to dwie kolumny. |
Position
| Wartość | W przepływie | top / left liczone od | Do czego |
|---|---|---|---|
static | tak | nie działają | Wartość domyślna. |
relative | tak | własnego miejsca | Małe przesunięcie, punkt odniesienia dla absolute. |
absolute | nie | pozycjonowanego przodka | Znaczek w rogu, podpis na obrazie, podmenu. |
fixed | nie | okna | Przycisk „Do góry”, pasek zawsze widoczny. |
sticky | tak | okna, po dojechaniu do niego | Menu przyklejane przy przewijaniu. Wymaga top. |
z-index ustawia kolejność nakładania. Większa liczba jest wyżej. Działa tylko z position innym niż static.
Znaczniki układu
| Znacznik | Do czego |
|---|---|
<header> | Baner, nagłówek strony: tytuł, logo. |
<nav> | Główne menu, grupa odnośników do podstron. |
<main> | Główna treść tej strony. Dokładnie jeden, poza banerem, menu i stopką. |
<section> | Część treści na jeden temat, zwykle z nagłówkiem. Panel lewy, panel prawy. |
<article> | Samodzielna całość: wpis, ogłoszenie, opinia. |
<aside> | Dodatek do treści: panel boczny, reklama, ciekawostka. |
<footer> | Stopka: autor, kontakt. |
<div> | Pudełko bez znaczenia, tylko dla CSS lub JS, np. kontener na panele. |