Przejdź do treści
INF.03 · Dział I

Projektowanie stron i Frontend (HTML5 i CSS3)

Znaczniki strukturalne i semantyczne HTML, formularze, multimedia, selektory CSS, model pudełkowy (Box Model), pozycjonowanie, tworzenie layoutów (Flexbox, Grid), responsywność (RWD, Media Queries)

Wstęp: frontend to dział, w którym punkty daje precyzja

W części praktycznej INF.03 arkusz podaje makietę strony i listę wymagań: „nagłówek o wysokości 100 px", „menu wyrównane do prawej", „formularz wysyłający dane metodą POST". Egzaminator nie ocenia, czy strona jest ładna — ocenia, czy każdy punkt z listy da się zobaczyć w przeglądarce i znaleźć w kodzie. W części pisemnej pytania są jeszcze bardziej dosłowne: który selektor ma wyższą specyficzność, ile wyniesie szerokość elementu przy ustawieniu box-sizing: border-box, który znacznik jest liniowy. Ten dział jest w całości do wyuczenia na pamięć i w całości do policzenia.

1

Szkielet dokumentu HTML5

Każde zadanie praktyczne zaczyna się tak samo: masz utworzyć plik index.html z poprawnym szkieletem. Ten szkielet musisz umieć napisać z pamięci w minutę, bo za brak deklaracji typu dokumentu albo kodowania znaków traci się punkty jeszcze zanim zacznie się właściwa strona.

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Krotki opis strony dla wyszukiwarek">
  <title>Serwis komputerowy - strona glowna</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
      <h1>Serwis komputerowy</h1>
  </header>

  <nav>
      <ul>
          <li><a href="index.html">Strona glowna</a></li>
          <li><a href="uslugi.html">Uslugi</a></li>
          <li><a href="kontakt.html">Kontakt</a></li>
      </ul>
  </nav>

  <main>
      <article>
          <h2>Naprawa laptopow</h2>
          <p>Diagnostyka w 24 godziny.</p>
      </article>
  </main>

  <aside>
      <h3>Godziny otwarcia</h3>
      <p>Pon-Pt 9:00-17:00</p>
  </aside>

  <footer>
      <p>Copyright 2026 Serwis komputerowy</p>
  </footer>
</body>
</html>
DOCTYPE

<!DOCTYPE html> to deklaracja typu dokumentu, a nie znacznik. Musi stać w pierwszej linii, przed <html>. Jej brak przełącza przeglądarkę w tryb zgodności wstecznej (quirks mode), w którym model pudełkowy liczony jest inaczej i strona rozjeżdża się bez widocznej przyczyny.

meta charset

<meta charset="UTF-8"> ustawia kodowanie znaków. Bez niego polskie znaki diakrytyczne wyświetlą się jako krzaczki. Musi stać jak najwyżej w sekcji <head>. Uwaga: sam plik też trzeba zapisać w UTF-8 — deklaracja nie naprawi pliku zapisanego w Windows-1250.

viewport

width=device-width, initial-scale=1.0 mówi przeglądarce mobilnej, żeby traktowała szerokość okna jako szerokość urządzenia i nie skalowała strony. Bez tego znacznika media queries w praktyce nie zadziałają na telefonie — to warunek konieczny RWD.

Co jeszcze mieszka w sekcji head
  • <title> — tekst na karcie przeglądarki i w wynikach wyszukiwania. Jedyny element sekcji head widoczny dla użytkownika. Jest obowiązkowy.
  • <link rel="stylesheet" href="style.css"> — dołączenie zewnętrznego arkusza stylów. Znacznik pusty, bez zamknięcia.
  • <script src="skrypt.js" defer></script> — skrypt JavaScript; atrybut defer odracza wykonanie do czasu zbudowania drzewa dokumentu. Znacznik <style> to wewnętrzny arkusz stylów, a <link rel="icon"> — ikona na karcie.
  • Atrybut lang="pl" w znaczniku <html> deklaruje język treści — korzystają z niego czytniki ekranowe i wyszukiwarki.

Znaczniki puste (samozamykające)

Nie mają treści ani znacznika zamykającego: <br>, <hr>, <img>, <input>, <meta>, <link>. W HTML5 zapis z ukośnikiem na końcu jest dopuszczalny, ale zbędny. Napisanie </img> to błąd składniowy.

2

Znaczniki semantyczne, blokowe i liniowe

Semantyka to nadawanie znaczenia fragmentom strony. Wizualnie <header> niczym nie różni się od zwykłego kontenera, ale wyszukiwarka i czytnik ekranowy wiedzą, że to nagłówek strony. Egzamin regularnie każe „zastąpić znaczniki ogólne odpowiednimi znacznikami semantycznymi HTML5" — trzeba znać ich listę i przeznaczenie.

Znacznik semantyczny → do czego służy → częsty błąd
ZnacznikDo czego służyCzęsty błąd
<header>Nagłówek strony lub sekcji: logo, tytuł, podtytuł.Mylenie z <head>. Head jest niewidoczny, header leży w body.
<nav>Blok nawigacji: menu główne, spis treści, okruszki.Wrzucanie do niego każdego odnośnika. Pojedynczy link w akapicie to nie nawigacja.
<main>Główna, unikalna treść dokumentu.Użycie kilka razy. Element main może wystąpić w dokumencie tylko raz.
<section>Tematycznie spójna sekcja, zwykle z własnym nagłówkiem.Traktowanie jak kontenera do stylowania. Do tego służy <div>.
<article>Samodzielna treść, sensowna po wyjęciu ze strony: wpis bloga, ogłoszenie, komentarz.Mylenie z <section>. Test: czy da się to opublikować osobno?
<aside>Treść poboczna: pasek boczny, reklama, notka na marginesie.Utożsamianie z „kolumną po prawej". To znaczenie, nie położenie.
<footer>Stopka strony lub sekcji: prawa autorskie, kontakt, autor wpisu.Przekonanie, że może być tylko jedna. Własną stopkę może mieć każdy article.
<figure>Ilustracja, schemat lub listing wraz z podpisem.Podpis wpisany jako <p> zamiast <figcaption>.
<div>Kontener bez znaczenia — wyłącznie do grupowania i stylowania.Budowanie z niego całej strony mimo istnienia odpowiedników semantycznych.
<figure>
  <img src="plyta.jpg" alt="Plyta glowna ATX z opisanymi zlaczami">
  <figcaption>Rys. 1. Rozmieszczenie zlaczy na plycie ATX</figcaption>
</figure>
Elementy blokowe (block)

Zaczynają się od nowej linii i domyślnie zajmują całą dostępną szerokość rodzica. Przyjmują szerokość, wysokość oraz wszystkie marginesy i dopełnienia.

div, p, h1–h6, ul, ol, li, table, form, header, nav, main, section, article, aside, footer, figure, blockquote, hr

Elementy liniowe (inline)

Płyną w linii tekstu i zajmują tylko tyle miejsca, ile potrzebuje ich treść. Ignorują ustawienia szerokości i wysokości oraz marginesy górny i dolny.

span, a, strong, em, b, i, img, input, label, button, small, sub, sup, code, br

Właściwość display — jak zmienić zachowanie

Podział na blokowe i liniowe to tylko wartość domyślna. Zmienia się ją właściwością display: block, inline, inline-block, flex, grid, none.



Wartość inline-block to hybryda: element stoi w linii jak liniowy, ale przyjmuje wymiary jak blokowy. To klasyczne rozwiązanie dla poziomego menu zbudowanego z listy.



Uwaga na różnicę: display: none usuwa element z układu (miejsce po nim znika), a visibility: hidden tylko go ukrywa — puste miejsce zostaje. To pytanie pojawia się regularnie.

3

Formularze i typy pól

Formularz to most między frontendem a PHP. Na egzaminie praktycznym prawie zawsze trzeba zbudować formularz, wysłać go metodą POST i odebrać dane w skrypcie. Kluczowa zasada: pole bez atrybutu name nie zostanie wysłane. To najczęstsza przyczyna sytuacji „formularz działa, ale skrypt nic nie dostaje".

<form action="zapisz.php" method="post">

  <label for="imie">Imie i nazwisko:</label>
  <input type="text" id="imie" name="imie" placeholder="Jan Kowalski" required>

  <label for="mail">Adres e-mail:</label>
  <input type="email" id="mail" name="email" required>

  <label for="haslo">Haslo:</label>
  <input type="password" id="haslo" name="haslo" minlength="8" required>

  <label for="wiek">Wiek:</label>
  <input type="number" id="wiek" name="wiek" min="18" max="99" step="1">

  <label for="data">Data zgloszenia:</label>
  <input type="date" id="data" name="data">

  <label for="usluga">Rodzaj uslugi:</label>
  <select id="usluga" name="usluga">
      <option value="">-- wybierz --</option>
      <option value="diagnostyka">Diagnostyka</option>
      <option value="naprawa" selected>Naprawa</option>
      <option value="czyszczenie">Czyszczenie</option>
  </select>

  <p>Priorytet zlecenia:</p>
  <input type="radio" id="p1" name="priorytet" value="normalny" checked>
  <label for="p1">Normalny</label>
  <input type="radio" id="p2" name="priorytet" value="pilny">
  <label for="p2">Pilny</label>

  <input type="checkbox" id="regulamin" name="regulamin" value="tak" required>
  <label for="regulamin">Akceptuje regulamin</label>

  <label for="opis">Opis usterki:</label>
  <textarea id="opis" name="opis" rows="5" cols="40"
            placeholder="Opisz objawy"></textarea>

  <input type="hidden" name="zrodlo" value="strona-www">

  <button type="submit">Wyslij zgloszenie</button>
  <button type="reset">Wyczysc</button>
</form>
Atrybuty znacznika form
  • action — adres skryptu, który odbierze dane. Pusty lub pominięty oznacza wysyłkę do tej samej strony.
  • methodget albo post. Domyślnie GET.
  • enctype — przy wysyłce plików konieczne multipart/form-data.
  • novalidate — wyłącza wbudowaną walidację przeglądarki.
  • target — gdzie otworzyć odpowiedź, np. _blank.
GET kontra POST
  • GET — dane doklejane do adresu po znaku zapytania, widoczne w pasku i w historii, ograniczona długość. Nadaje się do wyszukiwarek i filtrów, bo taki adres da się zapisać w zakładkach.
  • POST — dane w treści żądania, niewidoczne w adresie, brak praktycznego limitu długości, obsługa plików. Do logowania, rejestracji i zapisu do bazy.
  • POST nie jest szyfrowany — jest tylko niewidoczny w adresie. Poufność daje dopiero HTTPS. To ulubione pytanie-pułapka.
  • W PHP dane odbierasz z tablicy superglobalnej GET albo POST, indeksując ją wartością atrybutu name.
Typy pola input, które trzeba znać
typeEfektUwagi
textJednoliniowe pole tekstoweWartość przyjmowana, gdy pominiesz atrybut type
passwordZnaki maskowane kropkamiMaskuje tylko wygląd; bez HTTPS dane lecą jawnie
emailWalidacja formatu adresuNa telefonie zmienia układ klawiatury
numberPole liczbowe ze strzałkamiWspółpracuje z atrybutami min, max, step
radioWybór jednej opcji z grupyWszystkie pola grupy muszą mieć ten sam name i różne value
checkboxPole wielokrotnego wyboruNiezaznaczone nie jest wysyłane w ogóle
date / timeKalendarz lub zegarData wysyłana w formacie rok-miesiąc-dzień
fileWybór pliku z dyskuWymaga enctype multipart/form-data w znaczniku form
hiddenPole ukryte przed użytkownikiemWidoczne w kodzie źródłowym — nie na dane wrażliwe
range / colorSuwak / próbnik koloruKolor wysyłany jako zapis szesnastkowy
submit / resetWysłanie / wyczyszczenie formularzaAlternatywnie znacznik button z atrybutem type
label, id i name — trzy różne rzeczy

id identyfikuje element w dokumencie i musi być unikalny. name to nazwa, pod jaką dane trafią do skryptu na serwerze. Atrybut for w znaczniku label wskazuje id pola, a nie jego name. Poprawnie połączona etykieta sprawia, że kliknięcie w tekst ustawia kursor w polu i zaznacza pole wyboru — to również kryterium oceny dostępności.



Różnica pól tekstowych: <input type="text"> jest jednoliniowe, puste i ma wartość w atrybucie value. Natomiast <textarea> jest wieloliniowe, ma znacznik zamykający, a treść domyślną wpisuje się między znacznikami — nie w atrybucie value.



placeholder to podpowiedź znikająca po kliknięciu — nie zastępuje etykiety i nie jest wysyłana jako wartość pola. Z kolei required blokuje wysłanie pustego pola po stronie przeglądarki, ale walidację i tak trzeba powtórzyć w PHP — użytkownik może wysłać żądanie z pominięciem formularza.

4

Multimedia i tabele

Obrazy, dźwięk i film w HTML5 wstawia się bez żadnych wtyczek. Punktowanym szczegółem jest zawsze atrybut alt przy obrazie oraz podanie kilku formatów źródłowych dla audio i wideo.

<!-- Obraz: alt jest obowiazkowy -->
<img src="img/serwis.jpg" alt="Technik naprawiajacy laptopa" width="600" height="400">

<!-- Audio -->
<audio controls loop>
  <source src="dzwiek.mp3" type="audio/mpeg">
  <source src="dzwiek.ogg" type="audio/ogg">
  Twoja przegladarka nie obsluguje odtwarzacza audio.
</audio>

<!-- Wideo -->
<video width="640" height="360" controls poster="miniatura.jpg" muted>
  <source src="film.mp4" type="video/mp4">
  <source src="film.webm" type="video/webm">
  Twoja przegladarka nie obsluguje odtwarzacza wideo.
</video>
Obraz — o czym pamiętać
  • alt — tekst alternatywny czytany przez czytniki ekranowe i wyświetlany, gdy plik się nie wczyta. Wymagany przez standard; dla grafiki czysto dekoracyjnej zostawia się go pustym.
  • title — dymek po najechaniu kursorem; to nie jest zamiennik atrybutu alt. width i height podane w kodzie rezerwują miejsce i zapobiegają przeskakiwaniu treści podczas ładowania.
  • Formaty: JPG — zdjęcia, kompresja stratna; PNG — grafika z przezroczystością, bezstratna; GIF — animacje, 256 kolorów; SVG — grafika wektorowa, skaluje się bez utraty jakości; WebP — nowoczesny, mniejszy od JPG i PNG.
Audio i wideo — atrybuty
  • controls — pokazuje panel sterowania. Bez niego użytkownik nie ma jak włączyć odtwarzania.
  • autoplay — automatyczne odtwarzanie. Przeglądarki blokują je, jeśli nie towarzyszy mu muted.
  • loop — zapętlenie; preload — strategia wczytywania danych.
  • poster (tylko wideo) — obrazek wyświetlany przed startem odtwarzania.
  • Kilka znaczników source pozwala przeglądarce wybrać obsługiwany format. Tekst między znacznikami to komunikat zastępczy.
<table>
  <caption>Cennik uslug serwisowych</caption>
  <thead>
      <tr>
          <th>Usluga</th>
          <th>Czas</th>
          <th>Cena</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Diagnostyka</td>
          <td>24 h</td>
          <td>50 zl</td>
      </tr>
      <tr>
          <td>Wymiana dysku na SSD</td>
          <td>2 h</td>
          <td>120 zl</td>
      </tr>
  </tbody>
  <tfoot>
      <tr>
          <td colspan="2">Razem</td>
          <td>170 zl</td>
      </tr>
  </tfoot>
</table>

Tabela — punktowane szczegóły

<th> to komórka nagłówkowa (domyślnie pogrubiona i wyśrodkowana), a <td> to komórka danych. Atrybut colspan scala komórki w poziomie (w obrębie wiersza), a rowspan w pionie (w obrębie kolumny) — to najczęściej mylona para w całym dziale. Po scaleniu trzeba usunąć nadmiarowe komórki z odpowiednich wierszy, inaczej tabela wyjedzie poza obrys. Właściwość border-collapse: collapse scala podwójne obramowania sąsiednich komórek w jedną linię. Tabel nie używa się do budowania układu strony — od tego są Flexbox i Grid.

5

Style, selektory i specyficzność

Reguła CSS ma trzy części: selektor, właściwość i wartość. Zapis p { color: red; } znaczy „każdy akapit ma mieć czerwony tekst". Trudność zaczyna się wtedy, gdy do jednego elementu pasuje kilka reguł ustawiających tę samą właściwość — wtedy rozstrzyga specyficzność.

1. Inline (w atrybucie)

Styl wpisany w atrybucie style konkretnego znacznika. Ma najwyższy priorytet, ale dotyczy jednego elementu i miesza treść z wyglądem. Odradzany poza wyjątkami.

2. Wewnętrzne

Blok <style> w sekcji <head>. Działa na całą jedną stronę. Wygodne przy pojedynczym pliku, bezużyteczne przy serwisie z wieloma podstronami.

3. Zewnętrzne

Osobny plik .css dołączony znacznikiem <link>. Jedna zmiana działa na wszystkie podstrony, a plik trafia do pamięci podręcznej przeglądarki. Zalecany sposób i ten oczekiwany w zadaniach egzaminacyjnych.

Rodzaje selektorów
/* selektor elementu - wszystkie akapity */
p { color: #333333; }

/* selektor klasy - elementy majace class="ostrzezenie" */
.ostrzezenie { background-color: yellow; }

/* selektor identyfikatora - element majacy id="menu" (jeden w dokumencie) */
#menu { width: 100%; }

/* selektor grupujacy - ta sama regula dla kilku selektorow */
h1, h2, h3 { font-family: Arial, sans-serif; }

/* selektor potomka (spacja) - kazdy link WEWNATRZ nav, na dowolnym poziomie */
nav a { text-decoration: none; }

/* selektor dziecka - tylko bezposrednie dzieci elementu ul */
ul > li { list-style: square; }

/* selektor uniwersalny - wszystkie elementy */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* selektory atrybutu */
input[type="text"] { border: 1px solid gray; }
a[href^="https"]   { color: green; }

/* pseudoklasy - stan elementu */
a:hover     { color: red; }
a:visited   { color: purple; }
input:focus { outline: 2px solid blue; }
tr:nth-child(even)  { background-color: #f2f2f2; }
li:first-child { font-weight: bold; }
li:last-child  { border-bottom: none; }

/* pseudoelementy - fragment elementu, zapis z dwoma dwukropkami */
p::first-letter { font-size: 200%; }
p::before { content: "-- "; }
Specyficzność — punktacja

Gdy do elementu pasuje kilka reguł ustawiających tę samą właściwość, wygrywa ta o wyższej sumie punktów. Punkty liczysz, sumując wszystkie składniki selektora:

Składnik selektoraPunktyPrzykład
Styl inline (atrybut style)1000style="color: red"
Identyfikator100#menu
Klasa, pseudoklasa, atrybut10.aktywny, :hover, [type]
Element, pseudoelement1div, a, ::before
Selektor uniwersalny0*
Przykład rozwiązany — kto wygra konflikt

Treść: W arkuszu stylów znajdują się trzy reguły. Jakiego koloru będzie tekst odnośnika o klasie link, leżącego wewnątrz listy w elemencie o identyfikatorze menu?

nav ul li a   { color: green; }
.link         { color: blue; }
#menu li a    { color: red; }

Rozwiązanie:
reguła 1 — cztery elementy, czyli 1 + 1 + 1 + 1 = 4 punkty;
reguła 2 — jedna klasa, czyli 10 punktów;
reguła 3 — identyfikator i dwa elementy, czyli 100 + 1 + 1 = 102 punkty.

Wygrywa reguła trzecia, więc tekst będzie czerwony.



Zasady dodatkowe: przy równej specyficzności wygrywa reguła zapisana później w arkuszu — to działanie kaskady. Deklaracja z dopiskiem !important przebija wszystko, łącznie ze stylem inline, dlatego stosuje się ją wyjątkowo. Znaczenie ma też kolejność dołączania: jeśli plik CSS jest podpięty po bloku <style>, to przy tej samej specyficzności wygrają reguły z pliku.



Dziedziczenie: część właściwości (kolor, krój i rozmiar pisma, wyrównanie tekstu) przechodzi z rodzica na dzieci. Właściwości układu — marginesy, dopełnienia, obramowania, szerokość — nie są dziedziczone.

6

Model pudełkowy i pozycjonowanie

Każdy element to prostokątne pudełko złożone z czterech warstw, liczonych od środka na zewnątrz: treść (content), dopełnienie (padding), obramowanie (border) i margines zewnętrzny (margin). Zadanie „oblicz rzeczywistą szerokość elementu" to jeden z najpewniejszych punktów w całej kwalifikacji — pod warunkiem, że pamiętasz o właściwości box-sizing.

.karta {
  width: 300px;
  height: 150px;
  padding: 20px;              /* dopelnienie ze wszystkich stron */
  border: 5px solid #333333;  /* grubosc, styl, kolor */
  margin: 10px;               /* margines zewnetrzny */
  background-color: #f5f5f5;
}

/* Zapisy skrocone:
 padding: 20px;                  - wszystkie strony
 padding: 10px 20px;             - gora/dol, lewo/prawo
 padding: 10px 20px 15px;        - gora, lewo/prawo, dol
 padding: 10px 20px 15px 5px;    - gora, prawo, dol, lewo (zgodnie z zegarem)
 margin: 0 auto;                 - wysrodkowanie bloku w poziomie
*/
Klasyk egzaminacyjny — ile naprawdę zajmuje element .karta?

Wariant A: box-sizing: content-box (wartość domyślna)
Zadeklarowana szerokość dotyczy wyłącznie obszaru treści. Dopełnienie i obramowanie dokładane są na zewnątrz:



szerokość widoczna = 300 (treść) + 2 × 20 (padding) + 2 × 5 (border) = 300 + 40 + 10 = 350 px
miejsce zajęte w układzie = 350 + 2 × 10 (margin) = 370 px
wysokość widoczna = 150 + 40 + 10 = 200 px



Wariant B: box-sizing: border-box
Zadeklarowana szerokość obejmuje treść, dopełnienie i obramowanie razem. Pudełko nie rośnie — kurczy się obszar treści:



szerokość widoczna = 300 px (dokładnie tyle, ile w kodzie)
szerokość samego obszaru treści = 300 − 40 − 10 = 250 px
miejsce zajęte w układzie = 300 + 2 × 10 = 320 px



Wniosek: margines nigdy nie wlicza się do szerokości elementu — ani w jednym, ani w drugim modelu. Wpływa tylko na miejsce zajęte w układzie. Dlatego niemal każdy arkusz stylów zaczyna się od reguły * { box-sizing: border-box; } — dzięki niej dwie kolumny po 50% szerokości z dopełnieniem nadal mieszczą się obok siebie.

Padding kontra margin — różnice w praktyce
  • padding leży wewnątrz obramowania, więc przyjmuje kolor i obrazek tła elementu. Odsuwa treść od krawędzi pudełka.
  • margin leży na zewnątrz obramowania i zawsze jest przezroczysty. Odsuwa element od sąsiadów.
  • Marginesy pionowe sąsiadujących elementów zlewają się (margin collapsing): 20 px z dołu i 30 px z góry dadzą odstęp 30 px, a nie 50 px. Marginesy poziome nigdy się nie zlewają.
  • margin: 0 auto centruje element blokowy w poziomie, ale tylko wtedy, gdy ma ustawioną szerokość mniejszą od rodzica.
  • Margines ujemny jest dozwolony i przesuwa element w stronę sąsiada. Ujemne dopełnienie nie istnieje.
Pozycjonowanie — właściwość position
WartośćWzględem czegoZachowanie
staticWartość domyślna. Element stoi tam, gdzie postawi go normalny przepływ. Właściwości top, left, right, bottom oraz z-index są ignorowane.
relativewłasnej pierwotnej pozycjiPrzesuwa się o zadaną wartość, ale miejsce po nim zostaje puste — sąsiedzi się nie przesuwają. Tworzy układ odniesienia dla dzieci ustawionych jako absolute.
absolutenajbliższego przodka o pozycjonowaniu innym niż staticWypada z normalnego przepływu — miejsce po nim znika, sąsiedzi zajmują je natychmiast. Gdy żaden przodek nie jest pozycjonowany, odnosi się do całego dokumentu.
fixedokna przeglądarkiWypada z przepływu i nie przewija się razem ze stroną. Typowe zastosowania: przyklejone menu górne, przycisk powrotu na górę, okno modalne.
stickykontenera przewijaniaHybryda: zachowuje się jak relative do momentu osiągnięcia zadanego progu (np. top: 0), a potem przykleja się jak fixed. Wymaga podania co najmniej jednej wartości top, bottom, left lub right.

Kolejność nakładania się elementów pozycjonowanych ustala właściwość z-index — większa wartość znaczy „bliżej użytkownika". Działa wyłącznie na elementach o pozycjonowaniu innym niż static; to najczęstsza przyczyna narzekania, że „z-index nie działa".

/* Menu przyklejone do gory ekranu */
header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 80px;
  z-index: 100;
}

/* Uwaga: fixed wypada z przeplywu, wiec tresc wjechalaby pod naglowek.
 Trzeba ja odsunac o wysokosc naglowka: */
main { margin-top: 80px; }

/* Etykieta "NOWOSC" przypieta do rogu karty produktu */
.produkt { position: relative; }
.produkt .etykieta {
  position: absolute;
  top: 10px;
  right: 10px;
}

/* Pasek boczny przyklejajacy sie przy przewijaniu */
aside { position: sticky; top: 90px; }

7

Layout: Flexbox i CSS Grid

Zasada wyboru jest prosta: Flexbox układa elementy w jednej osi (rząd albo kolumna), Grid w dwóch naraz (wiersze i kolumny). Menu poziome, pasek przycisków, wyśrodkowanie w pionie — Flexbox. Cały układ strony z nagłówkiem, panelem bocznym i stopką — Grid. Obie techniki włącza się na kontenerze, a działają na jego bezpośrednich dzieciach.

Flexbox — pasek nagłówka z menu
/* HTML:
 <nav class="menu">
     <a href="index.html">Start</a>
     <a href="uslugi.html">Uslugi</a>
     <a href="kontakt.html">Kontakt</a>
 </nav>
*/

.menu {
  display: flex;                    /* wlacza Flexbox na kontenerze */
  flex-direction: row;              /* os glowna: poziomo (domyslnie) */
  justify-content: space-between;   /* rozklad wzdluz osi glownej */
  align-items: center;              /* wyrownanie w osi poprzecznej */
  flex-wrap: wrap;                  /* zawijaj, gdy zabraknie miejsca */
  gap: 20px;                        /* odstep miedzy elementami */
  padding: 0 30px;
  height: 70px;
  background-color: #222222;
}

.menu a {
  color: white;
  text-decoration: none;
  padding: 10px 15px;
}

/* Wlasciwosci ustawiane na elementach potomnych */
.logo     { flex: 0 0 150px; }   /* nie rosnie, nie kurczy sie, ma 150px */
.wypelnij { flex: 1; }           /* zajmuje cala wolna przestrzen */
.ostatni  { order: 99; }         /* zmiana kolejnosci bez ruszania HTML */

/* Wysrodkowanie w pionie i poziomie - najkrotszy przepis w CSS */
.ekran {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}
justify-content (oś główna)
  • flex-start — wszystko dosunięte do początku (domyślnie).
  • flex-end — dosunięte do końca.
  • center — wyśrodkowane.
  • space-between — pierwszy przy lewej, ostatni przy prawej, reszta równomiernie pomiędzy.
  • space-around — równe odstępy wokół każdego elementu (skrajne mają połowę).
  • space-evenly — wszystkie odstępy identyczne, także skrajne.
align-items (oś poprzeczna)
  • stretch — elementy rozciągają się na całą wysokość kontenera (domyślnie).
  • flex-start i flex-end — dosunięcie do góry albo do dołu.
  • center — wyśrodkowanie w pionie.
  • baseline — wyrównanie do linii bazowej tekstu.

Uwaga: po ustawieniu flex-direction: column osie się zamieniają — wtedy justify-content steruje pionem, a align-items poziomem. To ulubione pytanie-pułapka.

CSS Grid — kompletny układ strony
/* HTML:
 <div class="strona">
     <header>...</header>
     <nav>...</nav>
     <main>...</main>
     <aside>...</aside>
     <footer>...</footer>
 </div>
*/

.strona {
  display: grid;
  grid-template-columns: 200px 1fr 250px;   /* trzy kolumny */
  grid-template-rows: 100px auto 80px;      /* trzy wiersze */
  grid-template-areas:
      "naglowek naglowek naglowek"
      "menu     tresc    bok"
      "stopka   stopka   stopka";
  gap: 15px;
  min-height: 100vh;
}

header { grid-area: naglowek; }
nav    { grid-area: menu; }
main   { grid-area: tresc; }
aside  { grid-area: bok; }
footer { grid-area: stopka; }

/* Alternatywnie - bez nazw obszarow, przez numery linii siatki */
.baner {
  grid-column: 1 / 4;    /* od linii 1 do linii 4, czyli przez 3 kolumny */
  grid-row: 1 / 2;
}
.szeroki { grid-column: span 2; }   /* rozciagnij na dwie kolumny */

/* Galeria, ktora sama dobiera liczbe kolumn */
.galeria {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

Jednostka fr, funkcja repeat i numeracja linii

1fr to jedna część wolnej przestrzeni, jaka zostaje po rozdaniu miejsca kolumnom o stałej szerokości. Zapis grid-template-columns: 200px 1fr 250px znaczy: skrajne kolumny mają stałe 200 i 250 pikseli, a środkowa bierze całą resztę. repeat(3, 1fr) to skrót od trzech równych kolumn, a minmax(220px, 1fr) ustala szerokość minimalną i maksymalną. Słowo auto-fit każe przeglądarce zmieścić tyle kolumn, ile się da — dzięki temu galeria jest responsywna bez ani jednego media query.



Numeracja linii siatki zaczyna się od 1, a układ o trzech kolumnach ma cztery linie pionowe. Dlatego grid-column: 1 / 4 rozciąga element przez wszystkie trzy kolumny. Mylenie numeru kolumny z numerem linii to najczęstszy błąd w tym temacie.



Starsza technika układania treści to float: left i float: right. Element pływający wypada z przepływu, przez co kontener traci wysokość — trzeba go domknąć regułą clear: both albo overflow: hidden. Do budowania layoutów float już się nie używa, ale nadal pojawia się w zadaniach o oblewaniu obrazka tekstem.

8

Responsywność, jednostki i media queries

RWD (Responsive Web Design) to jedna strona, która dopasowuje układ do szerokości ekranu — w odróżnieniu od osobnej wersji mobilnej pod innym adresem. Składają się na nią trzy rzeczy: znacznik viewport w sekcji head, jednostki względne zamiast sztywnych pikseli oraz media queries.

Jednostki CSS
JednostkaWzględem czegoKiedy jej używać
pxJednostka bezwzględna — pikselObramowania, cienie, drobne odstępy. Nie skaluje się z ustawieniami użytkownika.
%Wymiaru elementu nadrzędnegoSzerokości kolumn i kontenerów.
emRozmiaru pisma rodzicaDopełnienia zależne od wielkości tekstu. Uwaga: zagnieżdżanie mnoży wartości.
remRozmiaru pisma elementu htmlRozmiary pisma i odstępy w całym serwisie. Bez efektu kuli śnieżnej.
vw / vh1% szerokości / wysokości oknaSekcje na pełny ekran, np. min-height: 100vh.
frCzęść wolnej przestrzeni w siatceWyłącznie w CSS Grid.

Domyślny rozmiar pisma w przeglądarce to 16 px, więc 1rem = 16px, 1.5rem = 24px, 0.875rem = 14px. Różnica em kontra rem na przykładzie: jeśli rodzic ma pismo 20 px, to dziecko z ustawieniem font-size: 1.5em dostanie 30 px, a z 1.5rem — zawsze 24 px, niezależnie od rodzica.

/* Podejscie mobile first: najpierw style dla telefonu,
 potem kolejne progi rozszerzaja uklad. */

.strona {
  display: grid;
  grid-template-columns: 1fr;   /* telefon: jedna kolumna */
  gap: 10px;
}

/* Tablet - od 768 pikseli wzwyz */
@media screen and (min-width: 768px) {
  .strona { grid-template-columns: 200px 1fr; }
  .menu   { flex-direction: row; }
}

/* Desktop - od 1024 pikseli wzwyz */
@media screen and (min-width: 1024px) {
  .strona { grid-template-columns: 200px 1fr 250px; }
  aside   { display: block; }
}

/* Wariant desktop first - warunek maksymalnej szerokosci */
@media screen and (max-width: 767px) {
  .menu { flex-direction: column; }
  aside { display: none; }
}

/* Styl dla wydruku */
@media print {
  nav, footer, .reklama { display: none; }
  body { color: #000000; background: #ffffff; }
}

/* Warunek orientacji urzadzenia */
@media (orientation: landscape) {
  .baner { height: 40vh; }
}

/* Obraz responsywny */
img { max-width: 100%; height: auto; }
Zasady, które warto znać na pamięć
  • Reguła media query ma budowę: znak małpy, słowo media, typ nośnika (screen, print, all), słowo and i warunek w nawiasie okrągłym.
  • Typowe punkty przełamania (breakpointy): około 480 px telefon, 768 px tablet, 1024 px laptop, 1280 px duży monitor. To konwencja, nie norma — dobiera się je pod projekt.
  • Mobile first — style bazowe piszesz dla najmniejszego ekranu, a media queries z min-width dokładają elementy przy większych. Podejście odwrotne (desktop first) korzysta z max-width.
  • Kolejność ma znaczenie: media queries umieszcza się po stylach bazowych, bo mają tę samą specyficzność i rozstrzyga kaskada. Bez znacznika viewport w sekcji head żadna z nich nie zadziała poprawnie na telefonie.
Najczęstsze pułapki egzaminacyjne
  • Doliczanie marginesu do szerokości elementu. Margin nigdy nie wchodzi w skład szerokości pudełka — ani przy content-box, ani przy border-box. Wpływa tylko na miejsce zajmowane w układzie.
  • Mylenie content-box z border-box. Przy domyślnym content-box element o szerokości 300 px z dopełnieniem 20 px i obramowaniem 5 px zajmuje 350 px. Przy border-box zajmuje dokładnie 300 px, bo kurczy się obszar treści.
  • Zamiana colspan z rowspan. Colspan scala w poziomie (w wierszu), rowspan w pionie (w kolumnie). Po scaleniu trzeba usunąć nadmiarowe komórki.
  • Pole formularza bez atrybutu name. Takie pole nie zostanie wysłane do skryptu — formularz „działa", ale dane nie docierają. Atrybut id służy do etykiet i CSS, nie do wysyłki. POST przy tym niczego nie szyfruje, tylko ukrywa dane przed paskiem adresu.
  • Liczenie specyficzności na oko. Jeden identyfikator (100 punktów) przebija dowolną liczbę klas i elementów. Przy remisie wygrywa reguła zapisana później.
  • Ustawianie szerokości elementowi liniowemu. Znaczniki span czy a ignorują width i height, dopóki nie zmienisz im właściwości display na block albo inline-block.
  • Brak znacznika viewport przy RWD. Media queries są napisane poprawnie, a na telefonie strona i tak wygląda jak pomniejszony desktop.
  • Pominięcie atrybutu alt przy obrazie i mylenie head z header. Dwa drobiazgi, dwa gotowe odjęte punkty: alt jest wymagany, a head to niewidoczna sekcja metadanych, nie widoczny nagłówek strony.
Sprawdź, ile z tego zostało w głowie

HTML i CSS wchodzą do głowy dopiero wtedy, gdy policzysz kilka pudełek i rozstrzygniesz kilka konfliktów selektorów bez zaglądania do notatek. Rozwiąż test z tego działu i zobacz, gdzie jeszcze masz luki.