Kurs HTML

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 i height 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 i height 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ów width i height.

    Całkowita Szerokość = width (gdzie width 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

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.