6.7. Box Sizing (box-sizing
)
Wprowadzenie: Jak obliczany jest rozmiar pudełka?
W poprzednich lekcjach dowiedzieliśmy się, że domyślnie właściwości width
i height
w CSS określają rozmiar tylko **obszaru treści (content area)** elementu. Padding i border są dodawane *na zewnątrz* tych wymiarów, co zwiększa całkowity rozmiar elementu na stronie.
To domyślne zachowanie (box-sizing: content-box;
) może być nieintuicyjne, zwłaszcza gdy chcemy, aby element miał dokładnie określoną szerokość całkowitą, wliczając w to padding i border.
Właściwość box-sizing
pozwala zmienić sposób, w jaki przeglądarka oblicza całkowitą szerokość i wysokość elementu.
Wartości dla box-sizing
Właściwość box-sizing
przyjmuje dwie główne wartości:
content-box
: Jest to **wartość domyślna**.width
iheight
odnoszą się tylko do obszaru treści. Padding i border są dodawane na zewnątrz.Całkowita Szerokość =
width
+padding-left
+padding-right
+border-left-width
+border-right-width
border-box
:width
iheight
określają całkowity rozmiar elementu, **włączając padding i border**. Obszar treści jest automatycznie zmniejszany, aby zmieścić padding i border wewnątrz zadanych wymiarówwidth
iheight
.Całkowita Szerokość =
width
(gdziewidth
obejmuje już padding i border)
Przykład porównawczy:
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid blue;
margin: 10px;
}
.content-box-example {
box-sizing: content-box; /* Domyślne */
background-color: lightyellow;
}
.border-box-example {
box-sizing: border-box;
background-color: lightcyan;
}
Obliczenia:
.content-box-example
(domyślnie):- Całkowita szerokość = 200px (width) + 20px (p-left) + 20px (p-right) + 5px (b-left) + 5px (b-right) = 250px
- Całkowita wysokość = 100px (height) + 20px (p-top) + 20px (p-bottom) + 5px (b-top) + 5px (b-bottom) = 150px
.border-box-example
:- Całkowita szerokość = 200px (zgodnie z
width
) - Całkowita wysokość = 100px (zgodnie z
height
) - Obszar treści zostanie automatycznie zmniejszony:
- Szerokość treści = 200px - 20px (p-left) - 20px (p-right) - 5px (b-left) - 5px (b-right) = 150px
- Wysokość treści = 100px - 20px (p-top) - 20px (p-bottom) - 5px (b-top) - 5px (b-bottom) = 50px
- Całkowita szerokość = 200px (zgodnie z
Jak widać, border-box
sprawia, że element zachowuje zadaną szerokość width
i wysokość height
, niezależnie od dodanego paddingu czy obramowania, co jest często bardziej przewidywalne i łatwiejsze w zarządzaniu layoutem.
Dlaczego border-box
jest tak popularny?
Model border-box
jest powszechnie uważany za bardziej intuicyjny dla projektantów i deweloperów, ponieważ:
- Łatwiejsze zarządzanie wymiarami: Ustawiając
width: 50%;
i dodając padding, element nadal zajmie dokładnie 50% szerokości rodzica, a nie więcej. - Prostsze tworzenie siatek (grids): Ułatwia tworzenie kolumn o stałej procentowej szerokości, które mają również padding lub border.
- Bardziej przewidywalne layouty: Zmiana paddingu lub obramowania nie "rozpycha" elementu i nie psuje układu sąsiednich elementów.
Z tych powodów, bardzo popularną praktyką w nowoczesnym web developmencie jest ustawienie box-sizing: border-box;
dla wszystkich elementów na stronie za pomocą globalnej reguły:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit; /* Wszystkie elementy dziedziczą box-sizing z html */
}
Ta konfiguracja sprawia, że border-box
staje się domyślnym modelem obliczania rozmiaru dla całej strony, co znacznie upraszcza pracę z layoutem.
Dziedziczenie box-sizing
Właściwość box-sizing
**nie jest dziedziczona** domyślnie. Oznacza to, że ustawienie jej na rodzicu nie wpływa na dzieci. Dlatego w powyższym przykładzie globalnego ustawienia używa się selektora uniwersalnego (*
) wraz z box-sizing: inherit;
, aby jawnie wymusić dziedziczenie tej właściwości z elementu html
na wszystkie elementy i pseudoelementy.
Zadania praktyczne
Zadanie 1 (z rozwiązaniem)
Stwórz dwa elementy div
obok siebie (użyj display: inline-block;
lub Flexbox). Każdemu nadaj width: 50%;
, padding: 15px;
i border: 1px solid black;
. Zaobserwuj, co się dzieje (prawdopodobnie nie zmieszczą się w jednej linii). Następnie dodaj globalną regułę ustawiającą box-sizing: border-box;
dla wszystkich elementów i zobacz różnicę.
Rozwiązanie:
HTML:
<div class="container">
<div class="column">Kolumna 1</div><div class="column">Kolumna 2</div>
</div>
Uwaga: Brak spacji między divami w HTML lub użycie Flexbox zapobiega problemom z odstępami inline-block.
CSS (bez border-box):
.column {
display: inline-block;
width: 50%;
padding: 15px;
border: 1px solid black;
background-color: lightgray;
vertical-align: top; /* Dla równego wyrównania */
}
/* Efekt: Kolumny nie mieszczą się w jednej linii, bo ich całkowita szerokość > 100% */
CSS (z border-box):
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
.column {
display: inline-block;
width: 50%;
padding: 15px;
border: 1px solid black;
background-color: lightgray;
vertical-align: top;
}
/* Efekt: Kolumny idealnie mieszczą się w jednej linii, każda zajmuje 50% szerokości rodzica. */
Zadanie 2 (do samodzielnego wykonania)
Stwórz element div
z width: 300px;
, padding: 50px;
i border: 10px solid red;
. Najpierw użyj domyślnego box-sizing: content-box;
i oblicz/sprawdź jego całkowitą szerokość. Następnie zmień na box-sizing: border-box;
i ponownie sprawdź całkowitą szerokość oraz obliczoną szerokość obszaru treści.
FAQ - Najczęściej zadawane pytania
Czy zawsze powinienem używać box-sizing: border-box;
?
W nowoczesnym web developmencie jest to bardzo powszechna i zalecana praktyka, ponieważ znacznie upraszcza tworzenie layoutów, zwłaszcza responsywnych i opartych na siatkach (grids). Większość frameworków CSS (jak Bootstrap, Tailwind) domyślnie stosuje border-box
dla wszystkich elementów.
Czy box-sizing
wpływa na marginesy?
Nie, właściwość box-sizing
wpływa tylko na to, jak obliczany jest rozmiar elementu w odniesieniu do width
, height
, padding
i border
. Marginesy (margin
) są zawsze dodawane na zewnątrz i nie są objęte obliczeniami box-sizing
.
Czy istnieją inne wartości dla box-sizing
?
Specyfikacja CSS definiuje głównie content-box
i border-box
. Istniały historyczne, specyficzne dla przeglądarek wartości (np. padding-box
), ale nie są one standardowe i nie należy ich używać.
Czy zmiana box-sizing
może zepsuć istniejący layout?
Tak, jeśli istniejący layout był tworzony z założeniem domyślnego content-box
, globalna zmiana na border-box
może zmienić obliczone rozmiary elementów i potencjalnie zaburzyć układ. Wprowadzając border-box
do istniejącego projektu, należy dokładnie przetestować layout.