CSS Flexbox i Grid - Kompletny Przewodnik z Pytaniami Rekrutacyjnymi

Sławomir Plamowski 13 min czytania
css css-grid flexbox frontend layout pytania-rekrutacyjne

Dziś Flexbox i CSS Grid to dwa filary każdego nowoczesnego layoutu. Jeśli przygotowujesz się do rozmowy rekrutacyjnej na stanowisko frontend developera, możesz być pewien, że pytania o te technologie padną. W tym przewodniku pokażę Ci nie tylko jak działają te narzędzia, ale przede wszystkim jak o nich mówić na rozmowie, żeby zrobić wrażenie.

Flexbox - Podstawy które musisz znać

Odpowiedź w 30 sekund

Kiedy rekruter zapyta "Czym jest Flexbox?", odpowiedz tak:

Flexbox to jednowymiarowy system layoutu w CSS, który pozwala na elastyczne rozmieszczanie elementów w kontenerze. Definiuję kontener przez display: flex, a następnie kontroluję układ właściwościami justify-content dla osi głównej i align-items dla osi poprzecznej. Flexbox automatycznie zarządza rozmiarem i rozmieszczeniem elementów, co czyni go idealnym do nawigacji, list i komponentów responsywnych.

Poczekaj na pytania uzupełniające.

Odpowiedź w 2 minuty (jeśli chcą więcej)

Flexbox opiera się na koncepcji dwóch osi. Oś główna (main axis) domyślnie biegnie poziomo, a oś poprzeczna (cross axis) pionowo. Kierunek można zmienić właściwością flex-direction.

Kluczowe właściwości kontenera to justify-content, który kontroluje rozmieszczenie na osi głównej (od flex-start przez center do space-between), oraz align-items dla osi poprzecznej. Dla elementów potomnych mamy flex-grow (jak bardzo element ma się rozciągać), flex-shrink (jak bardzo może się kurczyć) i flex-basis (bazowy rozmiar).

Pokażę na przykładzie - oto klasyczny pasek nawigacji:

/* Kontener nawigacji */
.navbar {
  display: flex;
  justify-content: space-between; /* Logo po lewej, linki po prawej */
  align-items: center;            /* Wyrównanie pionowe do środka */
  padding: 1rem 2rem;
}

/* Grupa linków */
.nav-links {
  display: flex;
  gap: 2rem; /* Odstępy między linkami bez marginesów */
}

Ten kod tworzy responsywny pasek nawigacji, gdzie logo jest po lewej stronie, a linki po prawej. Właściwość gap to nowoczesny sposób na odstępy - zastępuje stare hacki z marginesami.

CSS Grid - Dwuwymiarowa potęga

Odpowiedź w 30 sekund

Na pytanie "Czym różni się CSS Grid od Flexbox?":

CSS Grid to dwuwymiarowy system layoutu, który pozwala kontrolować zarówno wiersze, jak i kolumny jednocześnie. Podczas gdy Flexbox działa w jednym wymiarze i jest idealny dla komponentów, Grid sprawdza się przy tworzeniu całych layoutów stron. Definiuję siatkę przez display: grid i grid-template-columns lub grid-template-rows, a elementy automatycznie wypełniają komórki lub mogę je precyzyjnie rozmieszczać.

Odpowiedź w 2 minuty

Grid daje pełną kontrolę nad układem w dwóch wymiarach. Mogę zdefiniować dokładną liczbę kolumn, ich szerokości (w pikselach, procentach lub jednostkach fr), a następnie rozmieszczać elementy w konkretnych komórkach siatki.

Tu robi się ciekawie - Grid wprowadza jednostkę fr (fraction), która reprezentuje ułamek dostępnej przestrzeni. To eleganckie rozwiązanie problemu elastycznych layoutów:

/* Klasyczny layout strony z sidebar */
.page-layout {
  display: grid;
  grid-template-columns: 250px 1fr;      /* Stały sidebar, elastyczna treść */
  grid-template-rows: auto 1fr auto;      /* Header, treść, footer */
  min-height: 100vh;
  gap: 1rem;
}

/* Alternatywnie - nazwane obszary dla czytelności */
.page-layout-named {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Wzorzec, który mi się sprawdził: używam grid-template-areas gdy layout ma wyraźnie zdefiniowane sekcje. Kod staje się niemal samododokumentujący - patrząc na definicję obszarów, od razu widzę strukturę strony.

Klasyczny Problem: Wycentrowanie elementu

To pytanie pada na niemal każdej rozmowie rekrutacyjnej z CSS. Rekruter chce zobaczyć, czy znasz nowoczesne podejścia.

Rozwiązanie Flexbox (najprostsze)

/* Wycentrowanie elementu w kontenerze */
.container {
  display: flex;
  justify-content: center; /* Centrowanie poziome */
  align-items: center;     /* Centrowanie pionowe */
  height: 100vh;           /* Pełna wysokość viewportu */
}

Trzy właściwości - to wszystko. Kandydaci, którzy robią wrażenie, potrafią to napisać bez zastanowienia.

Rozwiązanie Grid (równie eleganckie)

/* Alternatywa z Grid - jeszcze krótsza */
.container {
  display: grid;
  place-items: center; /* Skrót dla align-items i justify-items */
  height: 100vh;
}

Właściwość place-items to skrót, który ustawia zarówno align-items jak i justify-items. Dwie linijki kodu do idealnego wycentrowania.

Czego unikać (przestarzałe podejścia)

Na rozmowie pokaż, że znasz różnicę między starym a nowym podejściem:

/* Stare podejście - działa, ale niepotrzebnie skomplikowane */
.old-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* Jeszcze starsze - wymaga znajomości wymiarów */
.older-center {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 100px;
  margin-top: -50px;  /* Połowa wysokości */
  margin-left: -100px; /* Połowa szerokości */
}

Jeśli rekruter zapyta dlaczego Flexbox jest lepszy - odpowiedz, że nie wymaga znajomości wymiarów elementu, działa z dynamiczną zawartością i jest czytelniejszy w utrzymaniu.

Właściwość flex - głębokie zrozumienie

Rekruterzy często pytają o skrótową właściwość flex. To świetny sposób na sprawdzenie, czy kandydat naprawdę rozumie Flexbox.

Odpowiedź w 30 sekund

flex to skrót łączący trzy właściwości: flex-grow, flex-shrink i flex-basis. flex: 1 oznacza flex-grow: 1, flex-shrink: 1, flex-basis: 0%, czyli element będzie się rozciągał i kurczył proporcjonalnie, zaczynając od zerowego rozmiaru bazowego. flex: 0 0 auto oznacza brak rozciągania, brak kurczenia i rozmiar bazowy oparty na zawartości.

Praktyczne przykłady

/* Trzy elementy dzielące przestrzeń równo */
.equal-columns {
  display: flex;
}

.equal-columns > * {
  flex: 1; /* Każdy element dostaje równą część przestrzeni */
}

/* Sidebar o stałej szerokości, reszta elastyczna */
.sidebar-layout {
  display: flex;
}

.sidebar {
  flex: 0 0 300px; /* Nie rośnie, nie kurczy się, stała szerokość 300px */
}

.content {
  flex: 1; /* Zajmuje resztę dostępnej przestrzeni */
}

/* Element który może się kurczyć, ale ma minimalny rozmiar */
.flexible-min {
  flex: 1 1 200px; /* Rośnie i kurczy się, bazowy rozmiar 200px */
  min-width: 150px; /* Nigdy nie będzie mniejszy niż 150px */
}

Wzorzec, który mi się sprawdził przy responsywnych layoutach: łączę flex z min-width lub max-width, żeby kontrolować graniczne przypadki.

Grid Template - Definiowanie siatki

Jednostka fr - elastyczne kolumny

Jednostka fr (fraction) to prawdziwa magia CSS Grid. Reprezentuje ułamek wolnej przestrzeni w kontenerze:

/* Trzy równe kolumny */
.three-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  /* Albo krócej: repeat(3, 1fr) */
  gap: 2rem;
}

/* Sidebar + główna treść w proporcji 1:3 */
.sidebar-main {
  display: grid;
  grid-template-columns: 1fr 3fr;
  gap: 2rem;
}

/* Elastyczne kolumny z minimalną szerokością */
.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

Ten ostatni przykład z auto-fit i minmax to jeden z najpotężniejszych wzorców w CSS Grid. Tworzy responsywną siatkę, która automatycznie dopasowuje liczbę kolumn do szerokości kontenera. Nie potrzebujesz media queries - Grid sam oblicza optymalny układ.

Pozycjonowanie elementów w siatce

/* Siatka 4x3 z precyzyjnym rozmieszczeniem elementów */
.precise-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 200px);
  gap: 1rem;
}

/* Element zajmujący dwie kolumny */
.wide-item {
  grid-column: span 2; /* Rozciąga się na 2 kolumny */
}

/* Element w konkretnym miejscu */
.positioned-item {
  grid-column: 2 / 4; /* Od linii 2 do linii 4 (dwie kolumny) */
  grid-row: 1 / 3;    /* Od linii 1 do linii 3 (dwa wiersze) */
}

/* Element zajmujący cały wiersz */
.full-width {
  grid-column: 1 / -1; /* Od pierwszej do ostatniej linii */
}

Notacja 1 / -1 to elegancki sposób na "od początku do końca" - minus jeden oznacza ostatnią linię siatki.

Responsywność bez media queries

Tu robi się naprawdę ciekawie. Zarówno Flexbox jak i Grid pozwalają tworzyć responsywne layouty bez pisania media queries.

Flexbox - flex-wrap

/* Karty które automatycznie się zawijają */
.card-container {
  display: flex;
  flex-wrap: wrap; /* Pozwala elementom przechodzić do nowej linii */
  gap: 1.5rem;
}

.card {
  flex: 1 1 300px; /* Rośnie, kurczy się, min. 300px */
  max-width: 400px; /* Opcjonalnie: maksymalna szerokość */
}

Karty będą się układać obok siebie dopóki jest miejsce. Gdy szerokość kontenera spadnie poniżej sumy minimalnych szerokości kart, automatycznie przejdą do następnego wiersza.

Grid - auto-fit z minmax

/* Galeria zdjęć - automatycznie responsywna */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* Wariant z auto-fill - zostawia puste komórki */
.gallery-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

Różnica między auto-fit a auto-fill: auto-fit rozciąga istniejące elementy żeby wypełnić przestrzeń, auto-fill zostawia puste komórki. W praktyce auto-fit jest używany częściej.

Align i Justify - kompletny przewodnik

Te właściwości często mylą kandydatów. Oto jasne wyjaśnienie:

We Flexbox

.flex-container {
  display: flex;

  /* Oś główna (domyślnie pozioma) */
  justify-content: flex-start;   /* Elementy na początku */
  justify-content: flex-end;     /* Elementy na końcu */
  justify-content: center;       /* Elementy w środku */
  justify-content: space-between;/* Równe odstępy, bez na brzegach */
  justify-content: space-around; /* Równe odstępy, połowa na brzegach */
  justify-content: space-evenly; /* Identyczne odstępy wszędzie */

  /* Oś poprzeczna (domyślnie pionowa) */
  align-items: stretch;     /* Rozciągnij do pełnej wysokości (domyślne) */
  align-items: flex-start;  /* Wyrównaj do góry */
  align-items: flex-end;    /* Wyrównaj do dołu */
  align-items: center;      /* Wyrównaj do środka */
  align-items: baseline;    /* Wyrównaj do linii bazowej tekstu */
}

/* Pojedynczy element może mieć inne wyrównanie */
.flex-item {
  align-self: flex-end; /* Ten element na dole, reszta wg kontenera */
}

W CSS Grid

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);

  /* Wyrównanie elementów w komórkach */
  justify-items: start;  /* Poziomo - do lewej */
  justify-items: end;    /* Poziomo - do prawej */
  justify-items: center; /* Poziomo - na środku */
  justify-items: stretch;/* Poziomo - rozciągnij (domyślne) */

  align-items: start;    /* Pionowo - do góry */
  align-items: end;      /* Pionowo - do dołu */
  align-items: center;   /* Pionowo - na środku */
  align-items: stretch;  /* Pionowo - rozciągnij (domyślne) */

  /* Wyrównanie całej siatki w kontenerze */
  justify-content: center; /* Cała siatka na środku poziomo */
  align-content: center;   /* Cała siatka na środku pionowo */
}

/* Skróty */
.grid-shortcuts {
  place-items: center;   /* Skrót dla align-items + justify-items */
  place-content: center; /* Skrót dla align-content + justify-content */
}

Zapamiętaj: justify- dotyczy osi inline (domyślnie poziomej), align- dotyczy osi block (domyślnie pionowej). place- to skróty łączące obie osie.

Gap - nowoczesne odstępy

Właściwość gap zastąpiła stare hacki z marginesami. Działa zarówno we Flexbox jak i w Grid:

/* Jednakowy odstęp wszędzie */
.uniform-gap {
  display: flex; /* lub grid */
  gap: 1.5rem;
}

/* Różne odstępy dla wierszy i kolumn */
.different-gaps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  row-gap: 2rem;    /* Odstęp między wierszami */
  column-gap: 1rem; /* Odstęp między kolumnami */
  /* Albo skrót: gap: 2rem 1rem; */
}

Dlaczego gap jest lepszy od marginesów? Nie musisz się martwić o marginesy na brzegach kontenera, nie ma problemów z margin collapse, i kod jest czytelniejszy.

Praktyczny przykład - dashboard

Połączmy wszystko w realnym przykładzie. Oto layout dashboardu używający Grid dla głównej struktury i Flexbox dla komponentów:

/* Główny layout dashboardu */
.dashboard {
  display: grid;
  grid-template-areas:
    "nav    nav"
    "sidebar main"
    "sidebar footer";
  grid-template-columns: 280px 1fr;
  grid-template-rows: 60px 1fr auto;
  min-height: 100vh;
}

.dashboard-nav {
  grid-area: nav;
  display: flex;           /* Flexbox dla nawigacji */
  justify-content: space-between;
  align-items: center;
  padding: 0 2rem;
  background: #1a1a2e;
}

.dashboard-sidebar {
  grid-area: sidebar;
  padding: 1.5rem;
  background: #16213e;
}

.dashboard-main {
  grid-area: main;
  padding: 2rem;

  /* Siatka kart wewnątrz głównej sekcji */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  align-content: start;
}

.dashboard-footer {
  grid-area: footer;
  padding: 1rem 2rem;
}

/* Karta w dashboardzie */
.dashboard-card {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: white;
  border-radius: 8px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.card-content {
  flex: 1; /* Rozciąga się żeby wypełnić kartę */
}

Ten wzorzec pokazuje najważniejszą zasadę: Grid dla makro-layoutu (struktura strony), Flexbox dla mikro-layoutu (komponenty wewnątrz).

Responsywność z media queries

Czasem potrzebujesz media queries. Oto wzorzec dla responsywnego dashboardu:

/* Mobile first - domyślnie jedna kolumna */
.dashboard {
  display: grid;
  grid-template-areas:
    "nav"
    "main"
    "footer";
  grid-template-columns: 1fr;
  grid-template-rows: 60px 1fr auto;
}

.dashboard-sidebar {
  display: none; /* Ukryty na mobile */
}

/* Tablet i większe - pokaż sidebar */
@media (min-width: 768px) {
  .dashboard {
    grid-template-areas:
      "nav    nav"
      "sidebar main"
      "sidebar footer";
    grid-template-columns: 250px 1fr;
  }

  .dashboard-sidebar {
    display: block;
  }
}

/* Desktop - szerszy sidebar */
@media (min-width: 1200px) {
  .dashboard {
    grid-template-columns: 300px 1fr;
  }
}

Podejście mobile-first oznacza, że piszesz najpierw style dla małych ekranów, a potem rozszerzasz je media queries min-width. To lepsza praktyka niż desktop-first z max-width.

Częste błędy i jak ich unikać

Błąd 1: Flexbox na całą stronę

/* Źle - Flexbox do layoutu całej strony */
.page {
  display: flex;
  flex-direction: column;
}

.main-content {
  display: flex;
}

.sidebar {
  flex: 0 0 250px;
}

.content {
  flex: 1;
}

/* Dobrze - Grid dla głównego layoutu */
.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
}

Błąd 2: Nadużywanie position: absolute

/* Źle - pozycjonowanie absolutne do layoutu */
.container {
  position: relative;
}

.box1 {
  position: absolute;
  top: 0;
  left: 0;
}

.box2 {
  position: absolute;
  top: 0;
  right: 0;
}

/* Dobrze - Flexbox lub Grid */
.container {
  display: flex;
  justify-content: space-between;
}

Błąd 3: Marginesy zamiast gap

/* Źle - marginesy z hackiem dla pierwszego/ostatniego elementu */
.items {
  display: flex;
}

.item {
  margin-right: 1rem;
}

.item:last-child {
  margin-right: 0;
}

/* Dobrze - właściwość gap */
.items {
  display: flex;
  gap: 1rem;
}

Na co rekruterzy naprawdę zwracają uwagę

Po latach przeprowadzania rozmów rekrutacyjnych wiem, że rekruterzy szukają kilku konkretnych rzeczy:

Kandydaci, którzy robią wrażenie, potrafią wybrać odpowiednie narzędzie do problemu. Nie używają Grid do prostej listy elementów, ale też nie próbują budować skomplikowanego layoutu samym Flexbox. Pokazują, że rozumieją kiedy co stosować.

Kolejna rzecz to znajomość nowoczesnej składni. gap zamiast margin hacków, place-items zamiast dwóch osobnych właściwości, fr units zamiast procent z calc(). To sygnalizuje, że kandydat śledzi rozwój CSS.

Wreszcie - umiejętność myślenia responsywnie od początku. Zamiast tworzyć desktop layout i potem "naprawiać" go na mobile, najlepsi kandydaci od razu myślą o elastycznych jednostkach i auto-fit/minmax.

Praktyka na koniec

Zanim pójdziesz na rozmowę, spróbuj rozwiązać te zadania:

Stwórz responsywną galerię zdjęć używając CSS Grid, która automatycznie dostosowuje liczbę kolumn do szerokości ekranu bez media queries.

Zbuduj pasek nawigacji z logo po lewej, linkami na środku i przyciskiem logowania po prawej. Na mobile wszystko powinno się zwinąć do hamburgera.

Zaprojektuj layout artykułu z główną treścią i sidebar, gdzie sidebar na mobile przenosi się pod główną treść.

Zaimplementuj siatkę kart produktów, gdzie jedna karta może być "wyróżniona" i zajmować dwa razy więcej miejsca niż pozostałe.

Te zadania pokrywają większość scenariuszy, które możesz spotkać na rozmowie. Ćwicz je aż będziesz w stanie napisać rozwiązanie bez zastanowienia.


Zobacz też


Chcesz więcej pytań rekrutacyjnych z CSS i frontend?

To tylko wycinek tego, co możesz spotkać na rozmowie rekrutacyjnej. Pełny zestaw pytań znajdziesz w naszych fiszkach, które pokrywają:

  • CSS selektory i specyficzność
  • Responsywny design i media queries
  • CSS Grid i Flexbox zaawansowane wzorce
  • Preprocesory CSS (SASS, LESS)
  • Animacje i transformacje
  • CSS-in-JS i CSS Modules

Sprawdź pełny zestaw fiszek dla frontend developerów

Możesz też wypróbować bezpłatny podgląd pytań z CSS, żeby zobaczyć jakość naszych materiałów.


Artykuł przygotowany przez zespół Flipcards na podstawie rzeczywistych doświadczeń z rozmów rekrutacyjnych i wieloletniej praktyki w tworzeniu interfejsów użytkownika.

Chcesz więcej pytań rekrutacyjnych?

To tylko jeden temat z naszego kompletnego przewodnika po rozmowach rekrutacyjnych. Uzyskaj dostęp do 800+ pytań z 13 technologii.

Kup pełny dostęp Zobacz bezpłatny podgląd
Powrót do blogu

Zostaw komentarz

Pamiętaj, że komentarze muszą zostać zatwierdzone przed ich opublikowaniem.