CSS od podstaw — w stronę INF.03
Ten sam układ co w części poświęconej JavaScriptowi: krótkie wyjaśnienie, potem przykład z gotowym rozwiązaniem (rozwiń, żeby zobaczyć kod), a obok analogiczne zadanie — bez rozwiązania, do zrobienia samodzielnie tą samą metodą.
Jak dołączamy CSS, klasy i id
CSS można dołączyć na trzy sposoby: inline (atrybut style bezpośrednio w tagu — do unikania w większych projektach), wewnętrznie (znacznik <style> w <head>) i zewnętrznie (osobny plik .css podłączony przez <link> — tak robimy na egzaminie INF.03). Atrybut class można nadać wielu elementom naraz (i jeden element może mieć kilka klas oddzielonych spacją) — w CSS łapiesz go kropką. Atrybut id musi być unikalny na całej stronie — tylko jeden element może go mieć — w CSS łapiesz go krzyżykiem.
Cały CSS piszesz wewnątrz znacznika <style>, umieszczonego w <head>. Wygodne do szybkich testów w jednym pliku.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Test</title>
<style>
h1 {
color: teal;
}
</style>
</head>
<body>
<h1>Cześć!</h1>
</body>
</html>
To ten sposób stosujemy w kursie i na egzaminie — style trzymamy w osobnym pliku .css, a stronę tylko do niego podłączamy.
<!-- index.html -->
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Cześć!</h1>
</body>
A plik CSS wygląda tak (bez żadnych tagów HTML):
/* style.css */
h1 {
color: teal;
}
Zasada: index.html + style.css + script.js w jednym folderze. Link do CSS zawsze w <head>.
Nadaj elementowi atrybut class="karta", a w CSS zbuduj dla niej styl kropką przed nazwą klasy. Tej samej klasy możesz użyć na wielu elementach.
Rozwiązanie
<div class="karta">Pierwsza karta</div>
<div class="karta">Druga karta</div>
.karta {
border: 1px solid #ccc;
border-radius: 8px;
padding: 16px;
}Nadaj jednemu, wybranemu elementowi atrybut id="glowny-naglowek" (id musi być unikalny — tylko jeden element na stronie może go mieć). W CSS napisz selektor #glowny-naglowek, który ustawi mu inny kolor tła niż pozostałym nagłówkom.
Jeden element może mieć kilka klas naraz, oddzielonych spacją w atrybucie class. Style z każdej klasy się sumują.
Rozwiązanie
<div class="karta wyrozniona">Karta wyróżniona</div>
.karta {
border: 1px solid #ccc;
padding: 16px;
}
.wyrozniona {
border-color: #E8A33D;
background: #2a2213;
}Do przycisku dodaj dwie klasy naraz: .przycisk (wspólny wygląd — padding, border-radius) oraz .niebezpieczny (czerwone tło, biały tekst — tylko dla przycisków usuwania). Sprawdź w przeglądarce, że efekty obu klas się łączą na jednym elemencie.
Selektory
Selektor mówi przeglądarce, do których elementów ma zastosować regułę. Selektor typu (p) łapie wszystkie elementy danego tagu, selektor klasy (.nazwa) — elementy z atrybutem class="nazwa", selektor id (#nazwa) — jeden konkretny element z id="nazwa". Selektor potomka (spacja między selektorami) łapie elementy zagnieżdżone wewnątrz innego elementu.
Zaznacz wszystkie akapity <p> na stronie i ustaw im granatowy kolor tekstu.
Rozwiązanie
p {
color: navy;
}Zaznacz wszystkie nagłówki <h2> i ustaw im zielony kolor tekstu.
Utwórz klasę .ostrzezenie z czerwonym tłem, białym tekstem i wewnętrznym odstępem, i zastosuj ją do jednego akapitu.
Rozwiązanie
<p class="ostrzezenie">Uwaga!</p>
.ostrzezenie {
background-color: red;
color: white;
padding: 10px;
}Utwórz klasę .sukces z zielonym tłem i białym tekstem. Zastosuj ją do diva z tekstem „Zapisano!”.
Nadaj jedynemu na stronie elementowi o id="naglowek" szare tło i wyśrodkowany tekst.
Rozwiązanie
<div id="naglowek">Tytuł strony</div>
#naglowek {
background-color: #e0e0e0;
text-align: center;
padding: 20px;
}Nadaj elementowi o id="stopka" ciemne tło (#222) i biały kolor tekstu.
Za pomocą selektora potomka pokoloruj na pomarańczowo linki znajdujące się wewnątrz diva o klasie .karta, nie ruszając linków poza nią.
Rozwiązanie
<div class="karta">
<a href="#">Link w karcie</a>
</div>
<a href="#">Link poza kartą</a>
.karta a {
color: orange;
}Za pomocą selektora potomka pokoloruj na biało wszystkie linki wewnątrz elementu <nav>, bez wpływu na linki poza nawigacją.
Model pudełkowy (box model)
Każdy element to prostokątne „pudełko” złożone z: treści (content), wewnętrznego odstępu (padding), obramowania (border) i zewnętrznego odstępu (margin). Właściwość box-sizing decyduje, czy zadeklarowana szerokość dotyczy samej treści (content-box, domyślnie), czy treści razem z paddingiem i obramowaniem (border-box).
Stwórz pudełko 200×100 px z wewnętrznym odstępem 20px i czarnym obramowaniem 2px.
Rozwiązanie
<div class="pudelko">Treść</div>
.pudelko {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid black;
}Stwórz pudełko 150×150 px z wewnętrznym odstępem 10px i czerwonym obramowaniem 3px.
Dodaj do pudełka z poprzedniego zadania zewnętrzny margines 30px z każdej strony, żeby odsunąć je od sąsiednich elementów.
Rozwiązanie
.pudelko {
margin: 30px;
}Ustaw różne marginesy z każdej strony innego pudełka: górny 10px, prawy 20px, dolny 10px, lewy 20px (podpowiedź: cztery osobne właściwości albo skrót margin: góra prawo dół lewo;).
Porównaj box-sizing: content-box i border-box dla dwóch pudełek o zadeklarowanej szerokości 200px, paddingu 20px i obramowaniu 5px.
Rozwiązanie
<div class="content-box">content-box</div>
<div class="border-box">border-box</div>
.content-box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 5px solid black;
/* rzeczywista szerokość = 200 + 2*20 + 2*5 = 250px */
}
.border-box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid black;
/* rzeczywista szerokość = 200px — padding i border mieszczą się w środku */
}Ustaw regułę * { box-sizing: border-box; } na całej stronie. W komentarzu w CSS zapisz własnymi słowami, dlaczego ta reguła jest tak często stosowana na początku projektu.
Kolory, jednostki i typografia
Kolor można zapisać jako nazwę (red), kod szesnastkowy (#ff0000) albo funkcję rgb() / rgba() (ta ostatnia z kanałem przezroczystości). Jednostki: px to wartość bezwzględna, % jest zależny od rodzica, em jest zależny od rozmiaru czcionki najbliższego rodzica, a rem — zawsze od rozmiaru czcionki elementu <html> (zwykle 16px).
Ustaw ten sam czerwony kolor tła trzem elementom, zapisany na trzy różne sposoby.
Rozwiązanie
.a { background-color: red; }
.b { background-color: #ff0000; }
.c { background-color: rgb(255, 0, 0); }Ustaw kolor tekstu na półprzezroczysty czarny za pomocą rgba(0, 0, 0, 0.5). W komentarzu opisz, czym różni się to od zwykłego color: black;.
Porównaj em i rem: rodzic ma font-size: 20px, jedno dziecko ma 1.5em, drugie 1.5rem.
Rozwiązanie
<div class="rodzic">
Rodzic (20px)
<span class="em-dziecko">Tekst 1.5em</span>
<span class="rem-dziecko">Tekst 1.5rem</span>
</div>
.rodzic { font-size: 20px; }
.em-dziecko { font-size: 1.5em; } /* 1.5 * 20px = 30px */
.rem-dziecko { font-size: 1.5rem; } /* 1.5 * 16px (html) = 24px */Zagnieźdź trzy divy jeden w drugim, każdemu ustaw font-size: 1.2em. Sprawdź w przeglądarce, jak rozmiar tekstu „mnoży się” z każdym kolejnym poziomem zagnieżdżenia — i zanotuj obserwację w komentarzu.
Ustaw podstawową typografię akapitu: krój czcionki z zapasowym (fallback), rozmiar, interlinię i grubość.
Rozwiązanie
p {
font-family: 'Georgia', serif;
font-size: 18px;
line-height: 1.6;
font-weight: 400;
}Ustaw nagłówkowi <h1> czcionkę bezszeryfową (np. 'Arial', sans-serif), rozmiar 32px, grubość 700 i interlinię 1.2.
Tło, obramowania i cienie
Tło może być obrazkiem (background-image) z ustawieniami rozmiaru, pozycji i powtarzania. border-radius zaokrągla rogi elementu, a box-shadow dodaje mu cień. Obramowanie można też ustawić tylko z jednej strony (border-bottom, border-left itd.).
Ustaw obrazek jako tło banera na pełną szerokość, wyśrodkowany, bez powtarzania i dopasowany rozmiarem do elementu.
Rozwiązanie
.baner {
background-image: url("tlo.jpg");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
height: 300px;
}Ustaw divowi tło w postaci drobnego, powtarzającego się wzoru (background-repeat: repeat), z dowolnym adresem obrazka.
Nadaj karcie zaokrąglone rogi i delikatny cień.
Rozwiązanie
.karta {
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}Zrób przycisk w pełni zaokrąglony (kształt „pigułki”, np. border-radius: 999px), z mocniejszym cieniem pojawiającym się po najechaniu myszką (:hover).
Dodaj obramowanie tylko od dołu elementu — przydatne np. do zakładek albo podkreślenia aktywnego linku.
Rozwiązanie
.zakladka {
border-bottom: 3px solid #4FD1C5;
padding-bottom: 8px;
}Zrób element z obramowaniem tylko z lewej strony (border-left), grubości 4px, symulujący wygląd cytatu (blockquote).
Pozycjonowanie
position: relative przesuwa element względem jego normalnego miejsca, nie wyjmując go z przepływu strony. position: absolute wyjmuje element z przepływu i pozycjonuje go względem najbliższego przodka z ustawionym position (innym niż domyślne static). position: sticky zachowuje się jak zwykły element, dopóki podczas przewijania nie dotrze do zadanej pozycji — wtedy się „przykleja”.
Przesuń element o 20px w dół i 10px w prawo względem jego normalnej pozycji.
Rozwiązanie
.przesuniety {
position: relative;
top: 20px;
left: 10px;
}Przesuń element o 15px w górę i 30px w lewo względem jego normalnej pozycji.
Umieść odznakę „Nowe” w prawym górnym rogu karty, korzystając z position: absolute wewnątrz position: relative.
Rozwiązanie
<div class="karta">
<span class="odznaka">Nowe</span>
Treść karty
</div>
.karta {
position: relative;
}
.odznaka {
position: absolute;
top: 8px;
right: 8px;
background: red;
color: white;
padding: 2px 8px;
border-radius: 4px;
}Umieść ikonkę zamknięcia „✕” w lewym górnym rogu okna modalnego (.modal, z position: relative), za pomocą position: absolute.
Zrób pasek nawigacji, który przykleja się do góry ekranu podczas przewijania strony.
Rozwiązanie
.pasek-nawigacji {
position: sticky;
top: 0;
background: white;
z-index: 100;
}Zrób nagłówek długiej tabeli, który pozostaje widoczny na górze podczas przewijania listy w dół (podpowiedź: position: sticky na elemencie <thead> lub jego komórkach).
Flexbox
display: flex zmienia sposób, w jaki dzieci danego elementu układają się względem siebie — domyślnie w rzędzie. justify-content steruje rozmieszczeniem wzdłuż głównej osi (poziomej), align-items — w poprzek (pionowo), a gap dodaje odstępy między elementami bez marginesów.
Rozłóż trzy elementy w rzędzie, równomiernie rozstawione na całej szerokości, wyśrodkowane w pionie.
Rozwiązanie
.kontener {
display: flex;
justify-content: space-between;
align-items: center;
}Rozłóż cztery elementy w rzędzie, wyśrodkowane poziomo (justify-content: center), z odstępem 16px między nimi (gap).
Wyśrodkuj pojedynczy element idealnie na środku kontenera — i w pionie, i w poziomie naraz.
Rozwiązanie
.kontener {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
}Tą samą metodą wyśrodkuj kartę logowania (formularz) na całej wysokości ekranu (height: 100vh).
Zbuduj galerię miniaturek, które zawijają się do kolejnego wiersza, gdy brakuje miejsca w bieżącym.
Rozwiązanie
.galeria {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.galeria img {
width: 150px;
}Zbuduj pasek nawigacji z wieloma linkami ułożonymi w rzędzie, które przy węższym oknie mają zawijać się do kolejnych wierszy zamiast wychodzić poza ekran.
Pseudoklasy i pseudoelementy
Pseudoklasy (:hover, :focus, :nth-child()) opisują stan lub pozycję elementu, który już istnieje w HTML-u. Pseudoelementy (::before, ::after) pozwalają dodać do elementu dodatkową treść wizualną bez zmiany kodu HTML.
Zmień kolor tła przycisku po najechaniu na niego myszką, z płynnym przejściem.
Rozwiązanie
.przycisk {
background: #4FD1C5;
transition: background 0.2s;
}
.przycisk:hover {
background: #38a89d;
}Zmień kolor obramowania pola tekstowego na niebieski, gdy jest ono aktywne — skorzystaj z pseudoklasy :focus.
Naprzemiennie pokoloruj wiersze tabeli („zebra stripes”), używając :nth-child(even).
Rozwiązanie
tr:nth-child(even) {
background-color: #f2f2f2;
}Wyróżnij co trzeci element listy innym kolorem tła, korzystając z :nth-child(3n).
Dodaj symbol cudzysłowu przed każdym elementem <blockquote>, bez zmiany kodu HTML.
Rozwiązanie
blockquote::before {
content: "❝ ";
color: #E8A33D;
font-size: 1.4em;
}Za pomocą ::after dodaj strzałkę „→” na końcu każdego linku wewnątrz elementu o klasie .czytaj-wiecej.
Responsywność (media queries)
@media pozwala zastosować reguły CSS tylko wtedy, gdy spełniony jest warunek — najczęściej dotyczący szerokości ekranu. Podejście mobile-first zakłada, że domyślne style piszemy dla małych ekranów, a modyfikacje dla większych dodajemy przez min-width.
Zmień układ galerii z rzędu na kolumnę, gdy ekran jest węższy niż 600px.
Rozwiązanie
.galeria {
display: flex;
gap: 12px;
}
.galeria .element {
flex: 1;
}
@media (max-width: 600px) {
.galeria {
flex-direction: column;
}
}Ukryj element o klasie .tylko-desktop (np. dodatkowe menu boczne), gdy szerokość ekranu jest mniejsza niż 768px (podpowiedź: display: none wewnątrz @media).
Zmniejsz rozmiar nagłówka głównego na małych ekranach, żeby zawsze mieścił się w jednej linii.
Rozwiązanie
h1 {
font-size: 48px;
}
@media (max-width: 480px) {
h1 {
font-size: 28px;
}
}Zmniejsz wewnętrzny odstęp karty (.karta) z 40px do 16px na ekranach węższych niż 500px.
Napisz reguły w podejściu mobile-first: domyślnie elementy paska ułożone są w kolumnie, a dopiero od szerokości 900px przechodzą w rząd.
Rozwiązanie
.pasek {
display: flex;
flex-direction: column;
}
@media (min-width: 900px) {
.pasek {
flex-direction: row;
}
}W podejściu mobile-first: domyślnie przyciski mają pełną szerokość (width: 100%), a od szerokości ekranu 768px mają szerokość automatyczną (width: auto) i wyświetlają się obok siebie.
Co dalej — trudniejsze partie materiału
Ta strona obejmuje solidne podstawy CSS: selektory, model pudełkowy, kolory i typografię, tło i cienie, pozycjonowanie, flexbox, pseudoklasy/pseudoelementy oraz responsywność. Do pełnego przygotowania do INF.03 w tym samym stylu (przykład + zadanie analogiczne) brakuje jeszcze:
- CSS Grid (
display: grid,grid-template-columns,grid-area) - Przejścia i animacje (
transition,@keyframes/animation) - Zmienne CSS (
:root { --nazwa: ...; }, funkcjavar()) - Stylowanie formularzy i elementów typowych dla makiet egzaminacyjnych (przyciski, pola, walidacja wizualna)
- Mini-projekt łączący flexbox/grid, media queries i animacje w jedną responsywną stronę
Poniżej, w rozmowie, masz gotowy prompt do wklejenia w tym samym lub innym oknie AI, żeby dokończyć te sekcje w dokładnie tym samym formacie i stylu HTML.