Kurs HTML i CSS · Moduł 4: Flexbox

Tworzenie Siatki za pomocą Flexbox

7 min czytania ·
W tej lekcji10

Masz do pokazania zdjęcia skarbów z grobowca: na komputerze po kilka w rzędzie, na telefonie jedno pod drugim. Starożytni Egipcjanie byli mistrzami planowania przestrzeni, od symetrycznych kolumn w świątyniach po precyzyjne podziały pól uprawnych wzdłuż Nilu. Tworzenie siatki (grid) za pomocą Flexbox to nowoczesny odpowiednik tej umiejętności. Przeanalizujemy krok po kroku, jak zbudować responsywny układ z elastycznymi kolumnami o szerokościach w procentach, podobnie jak robią to frameworki Bootstrap czy Tailwind CSS.

Krótka historia układów stron

W latach 90. układy stron budowano z tabel HTML, choć <table> służy do danych. W latach 2000. królowały float i clear, które znasz z lokacji o CSS. Flexbox, którego specyfikacja w obecnej postaci powstała w 2012 roku, pozwolił wreszcie ustawiać elementy w rzędzie bez sztuczek, a w 2017 roku przeglądarki wprowadziły CSS Grid, stworzony specjalnie do siatek dwuwymiarowych. Siatka na Flexboksie wciąż żyje, na przykład w Bootstrapie od wersji 4.

Dwie właściwości, na których stoi siatka

Siatkę budują dwie właściwości kontenera: display: flex ustawia elementy w rzędzie, a flex-wrap: wrap pozwala im przechodzić do nowej linii. Reszta to cztery kroki w stałej kolejności: włącz display: flex, dodaj flex-wrap: wrap, określ szerokość kolumn, na przykład flex-basis: 33%, a na koniec dodaj gap dla odstępów.

Krok 1: Stwórz podstawową strukturę dokumentu HTML

Najpierw stwórz nowy plik HTML i dodaj podstawową strukturę dokumentu. Dodaj element <div> z klasą .flex-grid i kilka elementów <div> z klasą .col, które będą reprezentować kolumny w siatce:

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="styles.css"> <!-- Podłącz plik CSS -->
  <title>Tworzenie Siatki za pomocą Flexbox</title>
</head>
<body>
  <div class="flex-grid">
    <div class="col col-6">Kolumna 1</div>
    <div class="col col-6">Kolumna 2</div>
  </div>
  <div class="flex-grid">
    <div class="col col-4">Kolumna 1</div>
    <div class="col col-4">Kolumna 2</div>
    <div class="col col-4">Kolumna 3</div>
  </div>
  <div class="flex-grid">
    <div class="col col-3">Kolumna 1</div>
    <div class="col col-3">Kolumna 2</div>
    <div class="col col-3">Kolumna 3</div>
    <div class="col col-3">Kolumna 4</div>
  </div>
</body>
</html>

Każdy wiersz to osobny .flex-grid. Kolumny mają wspólną klasę col i klasę liczbową, na przykład col-6, która mówi, ile z dwunastu części szerokości zajmie kolumna. W każdym wierszu liczby sumują się do 12.

Krok 2: Stwórz plik CSS

Otwórz lub utwórz nowy plik CSS i zapisz go jako styles.css. To do niego prowadzi znacznik <link> z kroku 1.

Krok 3: Stylizacja podstawowa

Dodaj podstawowe style dla elementów .flex-grid i .col, aby były widoczne na stronie. Tutaj siatka dostaje swoje dwie kluczowe właściwości:

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  gap: 20px;
  min-height: 100vh;
  background-color: #f0f0f0;
}

.flex-grid {
  display: flex;
  flex-wrap: wrap;
  width: 80%;
  background-color: #fff;
  border: 1px solid #ddd;
  padding: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  gap: 10px;
}

.col {
  background-color: lightblue;
  padding: 20px;
  text-align: center;
  border: 1px solid #ccc;
}

body jest kontenerem flex w kolumnie i układa wiersze jeden pod drugim. Każdy .flex-grid ma display: flex, flex-wrap: wrap i gap: 10px, a .col dostaje tło, wypełnienie i ramkę, żeby było ją widać.

Krok 4: Tworzenie klas kolumn z wartościami procentowymi

Dodaj style dla klas od .col-1 do .col-12, które określą szerokość kolumn w procentach. Wzór jest prosty: liczba z nazwy klasy podzielona przez 12:

.col-1 {
  flex-basis: 8.33333333%;
  max-width: 8.33333333%;
}

.col-2 {
  flex-basis: 16.66666667%;
  max-width: 16.66666667%;
}

.col-3 {
  flex-basis: 25%;
  max-width: 25%;
}

.col-4 {
  flex-basis: 33.33333333%;
  max-width: 33.33333333%;
}

.col-5 {
  flex-basis: 41.66666667%;
  max-width: 41.66666667%;
}

.col-6 {
  flex-basis: 50%;
  max-width: 50%;
}

.col-7 {
  flex-basis: 58.33333333%;
  max-width: 58.33333333%;
}

.col-8 {
  flex-basis: 66.66666667%;
  max-width: 66.66666667%;
}

.col-9 {
  flex-basis: 75%;
  max-width: 75%;
}

.col-10 {
  flex-basis: 83.33333333%;
  max-width: 83.33333333%;
}

.col-11 {
  flex-basis: 91.66666667%;
  max-width: 91.66666667%;
}

.col-12 {
  flex-basis: 100%;
  max-width: 100%;
}

flex-basis ustawia startową szerokość kolumny, a max-width działa jak bezpiecznik, gdyby ktoś dopisał kolumnie flex-grow. Dwanaście części wybrano celowo, bo 12 dzieli się przez 2, 3, 4 i 6. Jeśli nie chcesz liczyć, zostaw zapas: trzy kolumny z flex-basis: 30% przy typowych odstępach zmieszczą się w rzędzie.

Krok 5: Responsywne kolumny

Aby siatka była responsywna, możemy użyć media queries i zmieniać właściwości Flexbox w zależności od szerokości ekranu:

@media (max-width: 768px) {
  .flex-grid {
    flex-direction: column;
  }

  .col {
    flex: none;
    width: 100%;
  }
}

Na ekranach do 768 pikseli wiersz układa kolumny jedna pod drugą, a flex: none i width: 100% mają rozciągnąć je na całą szerokość.

Pułapka: padding, ramki i odstępy

Gdy otworzysz stronę, czeka cię niespodzianka: dwie kolumny col-6 nie staną obok siebie. Domyślnie flex-basis i max-width liczą samą treść kolumny, więc wypełnienie i ramka doliczają się do 50%, a do tego dochodzi odstęp. Suma przekracza 100% i druga kolumna spada do nowej linii. Na telefonie z kolei max-width z klas kolumn dalej obowiązuje. Naprawiają to trzy zmiany dopisane na końcu styles.css:

*,
*::before,
*::after {
  box-sizing: border-box;
}

.col-3 { flex-basis: calc(25% - 7.5px); max-width: calc(25% - 7.5px); }
.col-4 { flex-basis: calc(33.333% - 6.667px); max-width: calc(33.333% - 6.667px); }
.col-6 { flex-basis: calc(50% - 5px); max-width: calc(50% - 5px); }

@media (max-width: 768px) {
  .col {
    max-width: 100%;
  }
}

box-sizing: border-box, znane z lekcji o modelu pudełkowym, wlicza wypełnienie i ramkę do szerokości. Od każdej kolumny odejmujemy jej udział w odstępach, na przykład dwie kolumny col-6 dzielą jeden odstęp, więc każda oddaje 5 pikseli. Na telefonie max-width: 100% zdejmuje ograniczenie. Wzór na takie obliczenia poznasz w lekcji o gap.

Wynik

Po wykonaniu kroków od 1 do 5 twoje pliki powinny wyglądać następująco. Poprawki z poprzedniej sekcji dopisz na samym końcu arkusza, żeby nadpisały wcześniejsze reguły.

Plik HTML (index.html)

Plik HTML pozostaje bez zmian, to wciąż trzy wiersze z kolumnami:

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="styles.css"> <!-- Podłącz plik CSS -->
  <title>Tworzenie Siatki za pomocą Flexbox</title>
</head>
<body>
  <div class="flex-grid">
    <div class="col col-6">Kolumna 1</div>
    <div class="col col-6">Kolumna 2</div>
  </div>
  <div class="flex-grid">
    <div class="col col-4">Kolumna 1</div>
    <div class="col col-4">Kolumna 2</div>
    <div class="col col-4">Kolumna 3</div>
  </div>
  <div class="flex-grid">
    <div class="col col-3">Kolumna 1</div>
    <div class="col col-3">Kolumna 2</div>
    <div class="col col-3">Kolumna 3</div>
    <div class="col col-3">Kolumna 4</div>
  </div>
</body>
</html>

Plik CSS (styles.css)

Arkusz zbiera wszystkie reguły z kroków 3, 4 i 5 w jednym miejscu, w tej samej kolejności, w jakiej je pisałeś:

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  gap: 20px;
  min-height: 100vh;
  background-color: #f0f0f0;
}

.flex-grid {
  display: flex;
  flex-wrap: wrap;
  width: 80%;
  background-color: #fff;
  border: 1px solid #ddd;
  padding: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  gap: 10px;
}

.col {
  background-color: lightblue;
  padding: 20px;
  text-align: center;
  border: 1px solid #ccc;
}

.col-1 {
  flex-basis: 8.33333333%;
  max-width: 8.33333333%;
}

.col-2 {
  flex-basis: 16.66666667%;
  max-width: 16.66666667%;
}

.col-3 {
  flex-basis: 25%;
  max-width: 25%;
}

.col-4 {
  flex-basis: 33.33333333%;
  max-width: 33.33333333%;
}

.col-5 {
  flex-basis: 41.66666667%;
  max-width: 41.66666667%;
}

.col-6 {
  flex-basis: 50%;
  max-width: 50%;
}

.col-7 {
  flex-basis: 58.33333333%;
  max-width: 58.33333333%;
}

.col-8 {
  flex-basis: 66.66666667%;
  max-width: 66.66666667%;
}

.col-9 {
  flex-basis: 75%;
  max-width: 75%;
}

.col-10 {
  flex-basis: 83.33333333%;
  max-width: 83.33333333%;
}

.col-11 {
  flex-basis: 91.66666667%;
  max-width: 91.66666667%;
}

.col-12 {
  flex-basis: 100%;
  max-width: 100%;
}

@media (max-width: 768px) {
  .flex-grid {
    flex-direction: column;
  }

  .col {
    flex: none;
    width: 100%;
  }
}

Kolejność reguł ma znaczenie: media query stoi na końcu, więc na telefonie nadpisuje wcześniejsze ustawienia kolumn. Z tego samego powodu poprawki trafiają za nią. Moja rada: gdy układ potrzebuje wierszy i kolumn naraz, sięgnij po CSS Grid, a siatkę na Flexboksie zostaw dla prostych rzędów.

Zadanie dodatkowe

  1. Dodaj więcej kolumn i eksperymentuj z różnymi wartościami flex-basis i max-width, aby zobaczyć, jak zmienia się układ siatki.
  2. Przetestuj swoje umiejętności, tworząc bardziej złożone układy z użyciem różnych kombinacji właściwości Flexbox.
  3. Dodaj różne style do swojej siatki, np. zmieniając kolory, rozmiary czcionek i inne właściwości elementów, aby lepiej zrozumieć, jak działają różne opcje Flexboxa.

Wypróbuj siatkę w edytorze poniżej. Zobaczysz ją od innej strony: kontenery mają flex-wrap: wrap i stałą wysokość, więc elementy układają się w kilka linii, a align-content decyduje, jak te linie rozłożą się w pionie.

Kod do tej lekcji: index.html
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox - Align Content</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>Align Content - Rozmieszczanie linii</h1>
        <p class="subtitle">Kontroluj rozkład LINII elementów w kontenerze z flex-wrap</p>

        <section class="demo-section">
            <h2>align-content: flex-start</h2>
            <div class="flex-container align-start">
                <div class="flex-item">1</div>
                <div class="flex-item">2</div>
                <div class="flex-item">3</div>
                <div class="flex-item">4</div>
                <div class="flex-item">5</div>
                <div class="flex-item">6</div>
            </div>
            <p class="description">Linie są grupowane na początku kontenera</p>
        </section>

        <section class="demo-section">
            <h2>align-content: center</h2>
            <div class="flex-container align-center">
                <div class="flex-item">1</div>
                <div class="flex-item">2</div>
                <div class="flex-item">3</div>
                <div class="flex-item">4</div>
                <div class="flex-item">5</div>
                <div class="flex-item">6</div>
            </div>
            <p class="description">Linie są wycentrowane w kontenerze</p>
        </section>

        <section class="demo-section">
            <h2>align-content: space-between</h2>
            <div class="flex-container align-between">
                <div class="flex-item">1</div>
                <div class="flex-item">2</div>
                <div class="flex-item">3</div>
                <div class="flex-item">4</div>
                <div class="flex-item">5</div>
                <div class="flex-item">6</div>
            </div>
            <p class="description">Pierwsza linia na górze, ostatnia na dole, równe odstępy między</p>
        </section>

        <section class="demo-section">
            <h2>align-content: space-around</h2>
            <div class="flex-container align-around">
                <div class="flex-item">1</div>
                <div class="flex-item">2</div>
                <div class="flex-item">3</div>
                <div class="flex-item">4</div>
                <div class="flex-item">5</div>
                <div class="flex-item">6</div>
            </div>
            <p class="description">Równe odstępy wokół każdej linii</p>
        </section>

        <section class="demo-section practice">
            <h2>Praktyka: Egipska półka ze skarbami</h2>
            <p class="practice-description">Rozmieszczamy skarby faraona na półkach</p>

            <div class="shelf-container">
                <div class="shelf">
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                    <div class="treasure">◆</div>
                </div>
            </div>

            <div class="controls">
                <button onclick="changeAlign('flex-start')">Start</button>
                <button onclick="changeAlign('center')">Center</button>
                <button onclick="changeAlign('space-between')">Between</button>
                <button onclick="changeAlign('space-around')">Around</button>
            </div>
        </section>
    </div>

    <script>
        function changeAlign(value) {
            document.querySelector('.shelf').style.alignContent = value;
        }
    </script>
</body>
</html>

Pamiętaj: siatka na Flexboksie to pole nad Nilem podzielone na dwanaście równych części, gdzie flex-wrap: wrap pozwala zaczynać nowe rzędy, a procenty mówią, ile ziemi dostaje każda kolumna.

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Jakie dwie właściwości są niezbędne do stworzenia siatki (gridu) za pomocą Flexbox?

Zadania praktyczne w grze

  • Układanie w pionie

    Ułóż kroki tworzenia responsywnej siatki za pomocą Flexbox:

  • Edytor kodu

    Stwórz siatkę 3 kolumn z 6 elementami używając display: flex, flex-wrap: wrap i flex-basis: 30% na elementach potomnych.

  • Klikanie w kolejności

    Ułóż skrótową deklarację flex (grow: 1, shrink: 0, basis: 200px):

  • Układanie w pionie

    Ułóż metody tworzenia układu strony w CSS w kolejności chronologicznej:

Przydatne artykuły