HTML I CSS · INF.03 · MODUŁ 08
Box model, jednostki i typografia
Każdy element to pudełko. Gdy zrozumiesz jego budowę, przestaniesz zgadywać, dlaczego coś się rozjeżdża.
Wprowadzenie
Każdy element HTML jest pudełkiem. Przeglądarka rysuje je według modelu pudełkowego: w środku leży treść (content), wokół niej odstęp wewnętrzny (padding), potem ramka (border), a na zewnątrz odstęp (margin). Zrozumienie tych czterech warstw wystarcza, żeby przestać zgadywać, dlaczego coś jest szersze, niż wynika to z samej właściwości width.
Domyślnie obowiązuje box-sizing: content-box. Oznacza to, że width opisuje tylko treść, a padding i border dokładają się do całkowitego rozmiaru. Po ustawieniu box-sizing: border-box podana szerokość obejmuje już treść, padding i border. To wygodniejsze w układach, bo karta o szerokości 300px naprawdę zajmuje 300 px, niezależnie od paddingu.
Rozmiar ograniczają też min-width, max-width, min-height i max-height. Gdy treść nie mieści się w pudełku, decyduje overflow: visible pozwala jej wyjść na zewnątrz, hidden ją ucina, a auto dodaje pasek przewijania tylko wtedy, gdy jest potrzebny. Dla długich tabel i bloków kodu najbezpieczniejsze jest overflow-x: auto.
Jednostki dzielą się na stałe i względne. px to wartość stała. em zależy od rozmiaru czcionki bieżącego elementu, rem od czcionki root, % od rozmiaru rodzica, a vw i vh od szerokości i wysokości okna. Kolory zapisujemy jako hex (#2563eb), rgb() albo hsl(). Typografia opiera się na rodzinie czcionki, rozmiarze, grubości, interlinii, odstępie między literami i wyrównaniu tekstu.
/* Ten sam niebieski zapisany na trzy sposoby. */
color: #2563eb;
color: rgb(37, 99, 235);
color: hsl(221, 83%, 53%);
Ustaw box-sizing: border-box dla wszystkich elementów i ich pseudoelementów. Dzięki temu padding i border nie rozszerzają niespodziewanie kart, przycisków i pól formularza.
Najważniejsza własność
Najważniejsza jest umiejętność policzenia rzeczywistego rozmiaru pudełka. Przy content-box szerokość całkowita to szerokość treści plus dwa paddings i dwa bordery. Margines stoi poza tym rachunkiem: dodaje odstęp między pudełkami, ale nie powiększa samego elementu.
content-box: całkowita szerokość = width + 2·padding + 2·border
border-box: width obejmuje już content, padding i border
| Warstwa | Co robi | Wchodzi do width? |
|---|---|---|
| content | przechowuje tekst, obraz albo inne elementy | tak, to jest width przy content-box |
| padding | odstęp między treścią a ramką | tak przy content-box, nie przy border-box |
| border | ramka wokół paddingu i treści | tak przy content-box, nie przy border-box |
| margin | odstęp na zewnątrz, między elementami | nie, zawsze stoi poza pudełkiem |
Popatrz na różnicę w praktyce. Oba pudełka mają width: 300px, padding: 20px i border: 5px. Pierwsze zajmuje 350 px, bo 300 + 40 + 10 = 350. Drugie zajmuje dokładnie 300 px, a na treść zostaje 250 px.
.pudelko { width: 300px; padding: 20px; border: 5px solid #2563eb; }
.content { box-sizing: content-box; } /* 300 + 40 + 10 = 350 px */
.border { box-sizing: border-box; } /* całość 300 px, treść 250 px */
Gdy element ma być elastyczny, nie ustawiaj sztywnego width bez ograniczeń. Lepiej użyć max-width, na przykład max-width: 400px, i pozwolić elementowi zwęzić się na małym ekranie. min-width chroni przed zbyt dużym skurczeniem, a min-height przed zniknięciem sekcji z treścią.
overflow rozwiązuje problem treści większej niż pudełko. overflow: hidden ucina nadmiar, ale może ukryć ważną informację. overflow: auto dodaje pasek przewijania tylko wtedy, gdy treść naprawdę nie mieści się w środku. W tabelach i blokach kodu używaj overflow-x: auto, żeby długie linie dało się przewinąć w poziomie, zamiast rozjeżdżać całą stronę.
Ważne — licz, nie zgaduj. Zanim poprawisz układ, policz szerokość: content + padding + border. Potem sprawdź w narzędziach deweloperskich, czy przeglądarka pokazuje ten sam wynik. Dopiero wtedy zmieniaj box-sizing albo dodawaj max-width.
Most: od teorii do kodu
Policz pudełko i nazwij warstwy
Najpierw uzupełnij tabelę obliczeń, a potem wstaw brakujące właściwości do reguły CSS. Oba ćwiczenia korzystają z tego samego modelu.
Obliczenia dla content-box
śledzenie wartościUzupełnij wartości w pikselach. Pamiętaj, że padding i border występują po obu stronach pudełka.
.karta {
width: 240px;
padding: 12px 18px;
border: 4px solid #2563eb;
box-sizing: content-box;
}
| Element | Wartość (px) |
|---|---|
| szerokość content | |
| padding poziomo (lewy + prawy) | |
| border poziomo (lewy + prawy) | |
| całkowita szerokość |
Padding 12px 18px oznacza 12 px w pionie i 18 px w poziomie. Poziomo mamy 2 · 18 = 36 px. Border ma 4 px z każdej strony, czyli 8 px. Razem: 240 + 36 + 8 = 284 px.
Nazwij właściwości box modelu
uzupełnianie lukWybierz właściwości i wartość box-sizing, które pasują do komentarzy.
.karta {
width: 300px;
: 20px; /* odstęp wewnątrz ramki */
: 2px solid #2563eb; /* ramka */
: 16px auto; /* odstęp na zewnątrz */
box-sizing: ; /* width obejmuje padding i border */
}
padding to odstęp wewnątrz ramki, border to ramka, a margin odstęp na zewnątrz. border-box sprawia, że podana szerokość obejmuje padding i border.
Przykłady
Zbuduj zagnieżdżone prostokąty, które pokazują cztery warstwy pudełka. Podpisz margin, border, padding i content, a potem porównaj content-box z border-box.
<div class="margines">
<span class="podpis podpis-margines">margin 24px</span>
<div class="ramka">
<span class="podpis podpis-ramka">border 6px</span>
<div class="wypelnienie">
<span class="podpis podpis-padding">padding 24px</span>
<div class="tresc">
<strong>content</strong>320 × 160 px
</div>
</div>
</div>
</div>
.schemat, .schemat * { box-sizing: content-box; }
.margines {
position: relative;
width: 380px;
margin: 28px auto 18px;
padding: 24px;
border: 1px dashed #d97706;
background: #fffbeb;
}
.ramka {
position: relative;
border: 6px solid #ef4444;
background: #fef2f2;
}
.wypelnienie {
position: relative;
padding: 24px;
background: #dbeafe;
}
.tresc {
display: grid;
width: 320px;
height: 160px;
place-items: center;
outline: 1px dashed #64748b;
outline-offset: -1px;
background: #fff;
}
.podpis {
position: absolute;
padding: 3px 7px;
border: 1px solid #cbd5e1;
background: #fff;
font: 700 10.5px/1.3 Consolas, monospace;
}
.podpis-margines { top: 3px; right: 12px; color: #b45309; border-color: #fcd34d; }
.podpis-ramka { top: -13px; left: 12px; color: #b91c1c; border-color: #fca5a5; }
.podpis-padding { top: 4px; left: 10px; color: #1d4ed8; border-color: #93c5fd; }
<div class="porownanie">
<div class="pudelko content">width: 240px</div>
<div class="pudelko border">width: 240px</div>
</div>
.pudelko { width: 240px; padding: 20px; border: 5px solid #2563eb; }
.pudelko.content { box-sizing: content-box; } /* 290 px */
.pudelko.border { box-sizing: border-box; } /* 240 px */
- Content ma 320 × 160 px. To wewnętrzne pudełko z treścią, któremu ustawiliśmy
widthiheight. - Padding 24 px dodaje odstęp z każdej strony: do szerokości dochodzi 48 px, a do wysokości także 48 px.
- Border 6 px dodaje po 6 px z każdej strony: 12 px do szerokości i 12 px do wysokości. Razem pudełko ma 320 + 48 + 12 = 380 px szerokości i 160 + 48 + 12 = 220 px wysokości.
- Margin 24 px stoi na zewnątrz. Nie powiększa pudełka, tylko odsuwa je od sąsiadów. Dzięki temu schemat jest czytelny i nie dotyka krawędzi karty.
- W porównaniu content-box ma 240 + 40 + 10 = 290 px, a border-box przy tej samej wartości
width: 240pxzajmuje 240 px, bo padding i border są wliczone do środka.
Wynik: schemat pokazuje cztery warstwy, a porównanie wyjaśnia, dlaczego border-box ułatwia ustalanie szerokości.
Zbuduj pięć pasków o różnych szerokościach. Każdy podpisz jednostką i obliczeniem, żeby zobaczyć, od czego zależy jego długość.
<div class="skala">
<div class="wiersz px">
<span class="kod">200px</span>
<div class="tor"><div class="pasek"></div></div>
<span class="opis">stała szerokość</span>
</div>
<!-- pozostałe wiersze mają taką samą budowę -->
</div>
.skala { font-size: 20px; }
.px .pasek { width: 200px; } /* 200 px */
.em .pasek { width: 12em; } /* 12 · 20 = 240 px */
.rem .pasek { width: 12rem; } /* 12 · 16 = 192 px */
.procent .pasek { width: 50%; } /* połowa rodzica = 267 px */
.vw .pasek { width: 32vw; } /* 32% okna 1000 px = 320 px */
pxto wartość stała. Pasek 200 px ma 200 px niezależnie od rozmiaru czcionki i okna.emliczy się od czcionki bieżącego elementu. W tym demo.skalama 20 px, więc 12em daje 240 px.remliczy się od czcionki root. Domyślnie jest to 16 px, więc 12rem daje 192 px. Zmiana rozmiaru czcionki whtmlzmieni wszystkie wartości rem na stronie.%zależy od szerokości rodzica. Pasek 50% zajmuje połowę swojego kontenera. Przy szerokości 534 px daje to 267 px.vwzależy od szerokości okna. Przy oknie 1000 px pasek 32vw ma 320 px.vhdziała tak samo, ale liczy wysokość okna; używaj go ostrożnie, bo na telefonie pasek adresu zmienia wysokość.
Wynik: 200 px, 240 px, 192 px, 267 px i 320 px. Jednostki względne pozwalają projektować elastycznie, ale trzeba wiedzieć, od czego się liczą.
Zbuduj próbkę typografii: nagłówek, lead, tekst główny, mały tekst, rozstrzelony napis i cytat. Sprawdź rozmiar, interlinię, krój pisma oraz kontrast.
<div class="specimen">
<p class="eyebrow">Specimen · typografia</p>
<h1>Dobra typografia nie krzyczy</h1>
<p class="lead">Najpierw czytelność, potem ozdoby.</p>
<p class="tresc">Ten akapit ma 16 px i interlinię 1.75.</p>
<p class="mala">Mały tekst: 12,5 px i interlinia 1.45.</p>
<p class="rozstrzelony">Letter-spacing 0.18em</p>
<blockquote class="cytat">„Typografia to sztuka porządkowania tekstu.”</blockquote>
<div class="kontrast">
<div class="probka dobry">Kontrast dobry</div>
<div class="probka zly">Kontrast zbyt mały</div>
</div>
</div>
h1 {
font-family: Georgia, "Times New Roman", serif;
font-size: 42px;
line-height: 1.12;
letter-spacing: -.02em;
}
.lead { font-size: 20px; line-height: 1.5; }
.tresc { max-width: 520px; font-size: 16px; line-height: 1.75; }
.mala { font-size: 12.5px; line-height: 1.45; }
.rozstrzelony {
font-size: 13px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
}
.cytat {
font: italic 18px/1.5 Georgia, serif;
text-align: center;
}
.eyebrow {
font-size: 11px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
}
.probka { flex: 1 1 220px; padding: 12px 14px; border-radius: 9px; }
.dobry { background: #1c1917; color: #fff; }
.zly { background: #fff; color: #c7c2ba; }
.zly strong { color: #57534e; }
- Nagłówek ma 42 px, interlinię 1.12 i lekko ujemny letter-spacing. Duży tekst potrzebuje mniejszej interlinii niż akapit, bo inaczej rozpada się na luźne linie.
- Lead ma 20 px i interlinię 1.5. Wprowadza czytelnika w temat, ale nie konkuruje z nagłówkiem.
- Tekst główny ma 16 px i interlinię 1.75. Szerokość ograniczona do 520 px daje około 62 znaków w linii, co jest wygodne dla oka.
- Mały tekst ma 12,5 px i interlinię 1.45. Nadaje się do podpisów, ale nie do długiej lektury. Rozstrzelony napis używa
letter-spacing: .18emi wielkich liter. - Kontrast dobieraj do rozmiaru. Mały tekst powinien mieć co najmniej 4,5:1, a duży — 3:1. Jasnoszary tekst na białym tle wygląda elegancko, ale jest zbyt słabo czytelny.
Wynik: próbka pokazuje hierarchię tekstu, wygodną interlinię, kontrolowany letter-spacing i dwa skrajne przykłady kontrastu.
Spróbuj samodzielnie
W zadaniach najpierw policz pudełko, a potem dobierz jednostki i typografię. Wynik sprawdź w przeglądarce, bo dopiero tam widać, czy tekst nie wychodzi poza kartę i czy kontrast jest wystarczający.
Most: przewidź rozmiar
Jaka będzie szerokość pudełka?
Przeczytaj regułę i wybierz całkowitą szerokość. Zwróć uwagę na box-sizing.
Szerokość przy border-box
przewidywanieJaka jest całkowita szerokość tego elementu?
.box {
width: 200px;
padding: 20px;
border: 5px solid #2563eb;
box-sizing: border-box;
}
border-box wlicza padding i border do podanej szerokości. Całość ma 200 px, a na treść zostaje 200 − 40 − 10 = 150 px.
-
Element ma
width: 300px,padding: 15pxiborder: 3px solid. Oblicz całkowitą szerokość przybox-sizing: content-box.Pokaż rozwiązanie
Padding występuje po obu stronach: 2 · 15 = 30 px. Border także: 2 · 3 = 6 px. Całkowita szerokość to 300 + 30 + 6 = 336 px.
Gdyby element miał jeszcze
margin: 10px, margines nie wszedłby do tej sumy. Odsunąłby tylko element od sąsiadów, więc szerokość samego pudełka nadal wynosiłaby 336 px. -
Ten sam element ustawiono jako
box-sizing: border-boxzwidth: 300px,padding: 15pxiborder: 3px solid. Jaka jest szerokość treści i całkowita szerokość?Pokaż rozwiązanie
Całkowita szerokość wynosi 300 px, bo padding i border są już wliczone. Na treść zostaje 300 − 30 − 6 = 264 px.
To dlatego
border-boxtak dobrze sprawdza się w kartach: zmiana paddingu nie powiększa karty, tylko zmniejsza obszar treści. -
Karta ma
width: 100%,padding: 24pxiborder: 2px solid. W kontenerze o szerokości 600 px karta wystaje poza jego krawędź. Wyjaśnij przyczynę i zaproponuj poprawkę w CSS.Pokaż rozwiązanie
Przy
content-boxszerokość 100% oznacza 600 px treści, do tego dochodzi 48 px paddingu i 4 px borderu, czyli razem 652 px. Karta jest szersza od kontenera o 52 px.Poprawka: ustaw
box-sizing: border-boxna karcie (najlepiej globalnie dla wszystkich elementów). Wtedy 100% obejmuje padding i border, a karta ma dokładnie 600 px. Dodatkowo możesz ustawićmax-width: 100%ioverflow-wrap: break-word, żeby długie słowa nie rozpychały środka. -
Zaprojektuj krótkie ogłoszenie: ma mieć nagłówek, akapit i mały tekst pomocniczy. Dobierz rozmiary, interlinię, krój pisma i kontrast. Uzasadnij, dlaczego wybrane wartości są czytelne na telefonie.
Pokaż rozwiązanie
Przykład: nagłówek 24 px, grubość 700, interlinia 1.2; akapit 16 px, interlinia 1.6, szerokość ograniczona przez
max-width: 60chlubmax-width: 520px; mały tekst 13 px, interlinia 1.45. Tekst ciemny na jasnym tle, na przykład#1e293bna#ffffff, daje kontrast powyżej 12:1.Na telefonie nie zmniejszaj tekstu poniżej 16 px, bo łatwiej go przeczytać bez powiększania. Zamiast tego skróć linię i zwiększ interlinię. Kontrast sprawdź dla najmniejszego tekstu, nie tylko dla nagłówka.
Box model to content, padding, border i margin. Przy content-box padding i border dochodzą do width, a przy border-box są w niej zawarte. Używaj max-width i overflow-x: auto zamiast sztywnych szerokości. Jednostki względne uzależniają rozmiar od kontekstu, a typografia wymaga rozmiaru, interlinii i kontrastu dobranych do roli tekstu.