Na rozmowach z CSS najczęściej pada kilkanaście pytań: czym jest kaskada i specyficzność, jak działa model pudełkowy (*box model*), czym różnią się wartości właściwości position, kiedy użyć flexboxa, a kiedy gridu oraz jak działają jednostki i media queries. Rekruter nie sprawdza, czy pamiętasz wszystkie właściwości, tylko czy rozumiesz, dlaczego dana reguła działa albo nie działa. Dobra odpowiedź to jedno zdanie definicji i krótki przykład kodu.CSS wydaje się łatwy, dopóki nie trzeba wyjaśnić, dlaczego jedna reguła nadpisała drugą albo dlaczego element „nie chce” się wyśrodkować. Dlatego rekruterzy pytają o CSS w sposób, który szybko pokazuje, czy rozumiesz mechanizm, czy tylko kopiujesz rozwiązania. Poniżej znajdziesz pytania, które wracają na rozmowach na stanowisko juniora, razem z tym, jak na nie odpowiadać. CSS pracuje na strukturze HTML, więc jeśli jej jeszcze nie utrwaliłeś, zacznij od artykułu o pytaniach rekrutacyjnych z HTML, a po CSS przejdź do pytań z JavaScript.
Zachowanie przykładów z tego artykułu sprawdziliśmy w przeglądarce Chromium: specyficzność, model pudełkowy, pozycjonowanie, flexbox, siatkę, jednostki i media queries. Wyniki w tekście, np. wymiary elementów w pikselach, pochodzą z tych uruchomień.
Jak odpowiadać na pytania rekrutacyjne z CSS?
Najlepiej w trzech krokach: jedno zdanie definicji, krótki przykład (kilka linijek kodu albo sytuacja z projektu) i informacja, kiedy to ma znaczenie w praktyce. Taka odpowiedź zajmuje 30–60 sekund i pokazuje, że rozumiesz mechanizm, a nie wkułeś formułkę. Jeśli czegoś nie wiesz, powiedz, co wiesz, i rozumuj na głos. Rekruterzy oceniają sposób myślenia, a nie tylko wynik.
Pytania są ułożone od podstaw do tematów, które częściej pojawiają się przy ofertach na mid-poziom.
Podstawy CSS
Czym jest CSS i jak dołączyć go do strony?
CSS (Cascading Style Sheets) to język opisujący wygląd dokumentu HTML: kolory, odstępy, czcionki i układ. Można go dołączyć na trzy sposoby:
| Sposób | Przykład | Kiedy |
|---|---|---|
| Zewnętrzny arkusz | <link rel="stylesheet" href="style.css"> | domyślny wybór; plik jest cache’owany i wspólny dla stron |
Element <style> | <style>p { color: red; }</style> | krótkie style jednej strony, np. krytyczny CSS |
Atrybut style | <p style="color: red"> | wyjątkowo; ma bardzo wysoką specyficzność i trudno go nadpisać |
Jakie są rodzaje selektorów?
| Selektor | Przykład | Co wybiera |
|---|---|---|
| Typu | p | wszystkie akapity |
| Klasy | .card | elementy z class="card" |
| Identyfikatora | #header | element z id="header" |
| Potomka | nav a | linki w dowolnej głębokości wewnątrz nav |
| Dziecka | ul > li | tylko bezpośrednie dzieci |
| Atrybutu | input[type="email"] | elementy z danym atrybutem |
| Grupujący | h1, h2 | oba typy naraz |
Czym różni się pseudoklasa od pseudoelementu?
Pseudoklasa (jeden dwukropek, np. :hover, :focus, :first-child, :nth-child(2)) wybiera element w określonym stanie lub położeniu. Pseudoelement (dwa dwukropki, np. ::before, ::after, ::placeholder) wybiera wirtualną część elementu albo dodaje nową, której nie ma w HTML. Pseudoelementy ::before i ::after wymagają właściwości content, żeby się wyświetliły.
Jak wybrać rodzica elementu w CSS?
Przez lata odpowiedź brzmiała „nie da się”, bo CSS nie miał selektora rodzica (to jedno z najpopularniejszych pytań na Stack Overflow). Dziś mamy pseudoklasę :has(). Regułą div:has(> p.x) zaznaczysz tylko te <div>, które mają bezpośrednie dziecko <p class="x">. W naszym teście obramowanie dostał tylko <div> z takim dzieckiem, a drugi został bez zmian.
Kaskada i specyficzność
Czym jest kaskada?
Kaskada (cascade) to algorytm, który decyduje, która reguła wygra, gdy kilka dotyczy tej samej właściwości tego samego elementu. Bierze pod uwagę trzy rzeczy w tej kolejności: ważność (np. !important), specyficzność selektora i kolejność w kodzie. Gdy wszystko inne jest równe, wygrywa reguła, która pojawia się później.
Jak działa specyficzność selektorów?
Specyficzność (specificity) mówi, jak „mocny” jest selektor. Od najsłabszych do najsilniejszych: selektory typu i pseudoelementy, potem klasy, atrybuty i pseudoklasy, potem identyfikatory, na końcu atrybut style w HTML. W teście:
| Reguły | Element | Kolor | Dlaczego |
|---|---|---|---|
.a { color: red } i p { color: blue } | <p class="a"> | czerwony | klasa silniejsza niż typ, kolejność nie ma znaczenia |
#i { color: green } i .a { color: red } | <p id="i" class="a"> | zielony | identyfikator silniejszy niż klasa |
.a { color: red !important } i #i { color: green } | <p id="i" class="a"> | czerwony | !important wygrywa z identyfikatorem |
.a { color: red } i .b { color: green } | <p class="a b"> | zielony | ta sama specyficzność, późniejsza reguła wygrywa |
Ostatni wiersz kryje częstą pułapkę: o wyniku decyduje kolejność reguł w arkuszu, a nie kolejność klas w atrybucie class. Zamiana na class="b a" w teście dała ten sam kolor.
Dlaczego !important to ostateczność?
!important omija zwykłą specyficzność, więc jedynym sposobem na jego przebicie jest kolejne !important o większej specyficzności. Szybko prowadzi to do „wojny specyficzności”, w której nikt nie wie, która reguła w ogóle działa. Lepiej uporządkować selektory (np. metodą BEM, którą opisujemy w artykule o metodologii BEM w CSS) niż doklejać kolejne !important.
Czym jest dziedziczenie?
Część właściwości (np. color, font-family, line-height) przechodzi z rodzica na potomków automatycznie, inne (np. margin, border, padding, background) nie. W teście div { color: red } zmieniło kolor akapitu wewnątrz, choć akapit nie miał własnej reguły. Wartości inherit, initial i unset pozwalają sterować tym zachowaniem jawnie.
Model pudełkowy
Co to jest box model?
Każdy element w CSS jest prostokątnym pudełkiem złożonym z czterech warstw: zawartości (content), wypełnienia (padding), obramowania (border) i marginesu (margin). Szerokość, którą widzisz na stronie, to nie zawsze to samo, co width z CSS, bo zależy od box-sizing.
Czym różni się content-box od border-box?
W content-box (wartość domyślna) width dotyczy samej zawartości, a padding i obramowanie dodają się na zewnątrz. W border-box width obejmuje zawartość, padding i obramowanie. W teście <div> z width: 200px, padding: 10px i border: 1px miał realną szerokość 222 px w content-box i dokładnie 200 px w border-box. Dlatego w wielu projektach ustawia się globalnie * { box-sizing: border-box; }.
Czym różni się margin od padding?
padding to wewnętrzny odstęp między zawartością a obramowaniem i wchodzi w obszar tła elementu. margin to zewnętrzny odstęp od sąsiadów i jest przezroczysty. Margines służy do odsuwania elementów od siebie, a padding do „oddychania” zawartości w środku.
Co to jest zwijanie marginesów (margin collapse)?
Pionowe marginesy sąsiednich elementów blokowych łączą się w jeden, a odstęp równa się większemu z nich, a nie ich sumie. W teście margines dolny 30 px i górny 20 px dały odstęp 30 px, nie 50 px. Marginesy poziome się nie zwijają, a w kontenerach flexbox i grid też nie.
Layout i pozycjonowanie
Czym różnią się wartości display: block, inline, inline-block i none?
| Wartość | Zachowanie |
|---|---|
block | zaczyna nową linię, zajmuje całą szerokość, przyjmuje width, height i marginesy |
inline | mieści się w linii tekstu, ignoruje width i height oraz pionowe marginesy |
inline-block | układa się w linii jak tekst, ale przyjmuje width, height i marginesy |
none | element znika z układu, jakby go nie było |
Czym różni się display: none od visibility: hidden?
display: none usuwa element z układu strony, więc następny element wskakuje na jego miejsce. visibility: hidden ukrywa element, ale zostawia puste miejsce. W teście element po ukrytym przez display: none zaczynał się na górze strony (0 px), a po ukrytym przez visibility: hidden 20 px niżej, bo ukryty element nadal zajmował swoje miejsce. Czytniki ekranu zwykle pomijają oba, a ukrywanie tylko wizualne wymaga innych technik.
Jak działa position i czym różnią się jego wartości?
| Wartość | Zachowanie |
|---|---|
static | domyślna; element w normalnym przepływie, top/left nie działają |
relative | w normalnym przepływie, ale można go przesunąć; staje się punktem odniesienia dla potomków absolute |
absolute | wychodzi z przepływu, pozycjonowany względem najbliższego przodka z position innym niż static |
fixed | pozycjonowany względem okna przeglądarki, nie przewija się |
sticky | zachowuje się jak relative, aż przewijanie osiągnie wskazany próg, wtedy „przykleja się” |
Najczęstsze pytanie uzupełniające: względem czego jest pozycjonowany element absolute? W teście kontener position: relative o wymiarach 300×200 przesunięty o 100 px i 50 px miał wewnątrz element absolute z right: 0; bottom: 0, który znalazł się w jego prawym dolnym rogu. Ten sam element bez żadnego przodka z position wylądował w prawym dolnym rogu okna. Z kolei element sticky z top: 0 po przewinięciu strony o 500 px nadal był przyklejony do górnej krawędzi okna.
Jak działa z-index i czym jest kontekst nakładania?
z-index ustala kolejność nakładania się elementów pozycjonowanych (oraz elementów flex i grid). Częsta pułapka to kontekst nakładania (stacking context): niektóre właściwości (np. position z z-index, opacity poniżej 1, transform) tworzą własny, zamknięty „poziom”. Element wewnątrz takiego kontekstu nigdy nie wyjdzie ponad elementy z wyższego poziomu, nawet z ogromnym z-index. W teście element z z-index: 99 w kontenerze z z-index: 1 leżał pod elementem z z-index: 2 spoza kontenera.
Czym różni się flexbox od grida i kiedy którego użyć?
Flexbox układa elementy w jednym wymiarze (w rzędzie albo w kolumnie), a grid w dwóch naraz (wiersze i kolumny). Flexbox wybierasz do paska nawigacji, rzędu przycisków lub wyrównania elementów w kontenerze, a grid do układu całej strony lub siatki kart. Szerzej opisujemy to w artykule Flexbox czy CSS Grid.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
W teście ta reguła w kontenerze o szerokości 320 px dała trzy kolumny po 100 px z odstępem 10 px, a czwarty element zaczął nowy wiersz.
Jak wyśrodkować element w poziomie i w pionie?
To jedno z najczęściej zadawanych pytań, bo przez lata miało wiele rozwiązań. Dziś najprostsze to flexbox:
.container {
display: flex;
justify-content: center;
align-items: center;
}
W teście element 100×50 w kontenerze 400×200 trafił dokładnie na środek (x = 150, y = 75). Samo poziome wyśrodkowanie bloku o stałej szerokości to margin: 0 auto, a wyśrodkowanie tekstu w linii to text-align: center. Warto znać obie drogi, bo rekruter często dopytuje, co zrobić bez flexboxa.
Jednostki i responsywność
Czym różnią się jednostki px, em, rem, %, vh i dvh?
| Jednostka | Względem czego |
|---|---|
px | piksel CSS, wartość bezwzględna |
em | rozmiaru czcionki bieżącego elementu (dla font-size rodzica) |
rem | rozmiaru czcionki elementu <html> |
% | odpowiedniej wartości rodzica, zależnie od właściwości |
vw, vh | 1% szerokości lub wysokości okna |
dvh | 1% dynamicznej wysokości okna (uwzględnia paski przeglądarki w telefonie) |
Najczęstszy błąd to zagnieżdżone em, które się mnożą. W teście przy html { font-size: 20px } element z font-size: 2em wewnątrz rodzica z 2em miał 80 px, a z 2rem tylko 40 px. Dlatego do rozmiarów czcionek częściej wybiera się rem. O jednostkach wysokości okna na telefonie piszemy w artykule o nowych jednostkach CSS.
Jak działają media queries i czym jest podejście mobile-first?
Media queries (@media) włączają reguły tylko wtedy, gdy spełniony jest warunek, np. szerokość okna. Mobile-first oznacza pisanie stylów najpierw dla telefonu, a potem rozszerzanie ich dla większych ekranów przez min-width. W teście reguła @media (max-width: 600px) { p { color: red } } nie działała przy oknie 800 px, a przy 500 px już tak. Pełne omówienie znajdziesz w artykule o media queries w CSS. Pamiętaj też o <meta name="viewport"> w HTML, bez którego media queries nie zadziałają poprawnie na telefonie.
Nowoczesny CSS i organizacja kodu
Co to są zmienne CSS (custom properties)?
Zmienne CSS (custom properties) to wartości zapisane pod nazwą zaczynającą się od --, które odczytujesz przez var(). Dziedziczą się jak zwykłe właściwości, więc możesz je nadpisać w dowolnym kontenerze. W teście zmienna --c ustawiona na :root dała kolor rgb(1, 2, 3), a po nadpisaniu w kontenerze .o elementy w środku dostały rgb(9, 9, 9). Dzięki temu motyw ciemny lub inny wariant to zmiana kilku zmiennych, a nie wszystkich reguł.
:root {
--color-primary: #3b5bdb;
}
.button {
background: var(--color-primary);
}
Czym jest BEM i po co się go stosuje?
BEM (Block, Element, Modifier) to konwencja nazewnictwa klas, np. card__title--large. Utrzymuje niską i równą specyficzność, bo wszystko jest oparte na klasach, i pozwala odgadnąć strukturę po samej nazwie. Opisujemy ją szerzej w artykule o metodologii BEM w CSS i Sass.
Czym różni się Sass od SCSS?
Sass to preprocesor CSS, który dodaje m.in. zmienne, zagnieżdżanie, mixiny i importy. SCSS to nowsza składnia Sassa, wyglądająca jak zwykły CSS (z nawiasami klamrowymi i średnikami), a oryginalna składnia Sass opiera się na wcięciach. W praktyce w większości projektów spotkasz SCSS.
Jak załadować własną czcionkę?
Przez regułę @font-face, w której podajesz nazwę fontu i plik. Pełny przykład z formatami znajdziesz w artykule o własnych fontach w CSS z @font-face.
Zadania z kodem i mini-test
Jakie zadania z CSS pojawiają się na rozmowach?
Najczęściej to krótkie zadania typu: „wyśrodkuj ten element”, „ułóż trzy karty w rzędzie, które na telefonie przechodzą w kolumnę”, „dlaczego ten kolor się nie zmienia” albo „zbuduj prosty pasek nawigacji”. Przy takich zadaniach liczy się to, czy rozumiesz, dlaczego coś działa. Mów na głos, który mechanizm wybierasz i dlaczego.
Jaki kolor będzie miał ten akapit? Mini-test na rozgrzewkę
#box p { color: blue; }
.text { color: red; }
p.text { color: green; }
p { color: orange !important; }
<div id="box">
<p class="text">Ala ma kota</p>
</div>
Odpowiedź: pomarańczowy. Reguła p { color: orange !important } jest oznaczona jako ważna, więc wygrywa z każdą zwykłą regułą, także z #box p o wyższej specyficzności. Bez !important wygrałby niebieski (#box p ma identyfikator), potem zielony, a dopiero na końcu czerwony. Dobra odpowiedź na rozmowie nazywa wszystkie trzy kroki: ważność, specyficzność, kolejność.
Jak przygotować się do rozmowy z CSS?
- Zbuduj stronę bez gotowych bibliotek. Układ z flexboxa i gridu, kilka kart i menu, które zwija się na telefonie. Zrób to bez Bootstrapa.
- Poćwicz w narzędziach deweloperskich. Zakładka Elements pokazuje, które reguły są przekreślone i dlaczego, a to najlepszy trening specyficzności.
- Rozwiąż klasyczne zadania. Wyśrodkowanie, układ trzech kolumn, przyklejony nagłówek, dwie kolumny o równej wysokości.
- Przećwicz odpowiedzi na głos. Dla każdego pytania z tego artykułu sformułuj w 30 sekund definicję i przykład.
Na czym juniorzy najczęściej tracą punkty?
Nie na trudnych tematach, tylko na trzech drobiazgach, które wychodzą dopiero przy pytaniach uzupełniających:
- Dodawanie
!importantna ślepo. Zamiast zrozumieć specyficzność, junior dokłada kolejne!importanti traci kontrolę nad stylami. Pokaż, że wiesz, jak sprawdzić, która reguła wygrywa. - Mylenie
marginzpaddingi brak wiedzy obox-sizing. Odpowiedź „to odstępy” nie wystarczy. Wyjaśnij, gdzie które się znajduje i jak wpływają na szerokość elementu. - Absolute bez kontekstu. Mówienie, że
position: absolute„pozycjonuje względem strony”, jest błędem. Poprawna odpowiedź to najbliższy przodek zpositioninnym niżstatic.
Jak brzmi dobra odpowiedź, a jak słaba?
Weźmy pytanie o em i rem:
| Odpowiedź | Dlaczego | |
|---|---|---|
| Słaba | „em i rem to jednostki względne, rem jest nowszy.” | Brak różnicy w zachowaniu. Pytanie uzupełniające („ile pikseli ma 2em w zagnieżdżonym elemencie?”) od razu to pokaże. |
| Dobra | „em liczy się od rozmiaru czcionki rodzica, więc zagnieżdżone elementy się mnożą. rem liczy się zawsze od elementu html, więc jest przewidywalne. Rozmiary czcionek ustawiam w rem.” | Jest różnica w zachowaniu, konsekwencja i uzasadnienie wyboru. |
Ten sam schemat działa przy każdym pytaniu z tego artykułu: definicja, mechanizm, przykład użycia.
Co zrobić, gdy nie znasz odpowiedzi?
Nie zgaduj i nie milcz. Powiedz, co wiesz na pewno, a potem rozumuj na głos, np.: „Nie pamiętam dokładnej kolejności w liczeniu specyficzności, ale wiem, że identyfikator jest silniejszy niż klasa, a sprawdziłbym to w narzędziach deweloperskich.” Taka odpowiedź pokazuje, że potrafisz sobie poradzić w pracy, a umiejętność znalezienia odpowiedzi jest w codziennej pracy ważniejsza niż pamięć do szczegółów.
Jeśli dopiero planujesz ścieżkę nauki, CSS opanujesz najszybciej, budując prawdziwe strony razem z HTML i JavaScriptem. W naszym programie robisz to na ścieżce nauki frontendu z mentorem. Ogólny przebieg całego procesu rekrutacji opisujemy w poradniku jak przygotować się do rekrutacji na juniora.


