HTML5 & CSS3

Box-sizing – powrót do przeszłości

Box model to sposób interpretacji marginesów (paddingów) i szerokości poszczególnych elementów, korzystamy z niego od czasów starych, (nie)dobrych tabelek. Ci, którzy walczyli z różnymi wersjami IE (głównie 6) znają problem, który utrudniał życie wielu osobom – IE posiadał inny model pudełkowy, w którym padding dodawany był do szerokości kontenera w przeciwieństwie do modelu realizowanego w pozostałych przeglądarkach i zgodnego ze specyfikacjami W3C.

Dla przypomnienia zobaczmy czym dokładnie różnią się oba modele:

Model pudełkowy IE6: szerokość = width (tzw. border-box)
Model pudełkowy W3C: szerokość = width + padding + border (tzw. content-box)

Przez wiele lat developerzy korzystali ze standardu W3C jednocześnie pamiętając o pewnych trikach pomagających pisać kod działający także pod IE. Któż nie męczył się z wieloma błędami występującymi jedynie pod IE6? Model pudełkowy był jednym z wielu odstępstw Internet Explorera od jasno określonego standardu i zmorą dla osób, które musiały wspierać przeglądarkę Microsoftu.

Po wielu latach, kiedy IE6 jest już tylko złym wspomnieniem z dzieciństwa, a nowi developerzy nie znają już nawet „ułomnego” modelu pudełkowego IE, nadchodzi nowa moda na powrót do starych nawyków. Jak się okazuje są osoby, które twierdzą, że box model oferowany kiedyś przez IE okazuje się być wygodniejszy w użyciu w dzisiejszych projektach. Nie byle jakie osoby, bo głównym zwolennikiem tego podejścia jest słynny Paul Irish. Mniej entuzjastyczny jest David Storey, który mimo wszystko pozostaje ostrożnym optymistą. Swoje trzy grosze dorzuca także Chris Coyier. Zobaczmy jak w ogóle można wymusić inny model pudełkowy na danej przeglądarce:

* {box-sizing: border-box;}

Jak widać jest to banalnie proste i sprowadza się do jednej linijki CSS. Problemem może być raczej podejście developerów a nie ograniczenia techniczne – w końcu jest to dosyć istotna zmiana, która niesie ze sobą duże konsekwencje. Paul Irish komentuje to tak: „Jeśli ustawię elementowi 200px szerokości, to chcę, żeby ten element miał dokładnie 200px szerokości niezależnie od tego, czy padding będzie wynosił 10px czy 20px”. Trudno się z tym nie zgodzić. Z drugiej strony standardów się nie zmieni, bo to popsułoby wyświetlanie się wielu stron stworzonych do tej pory. Pozostaje jedynie stosowanie odpowiedniego box-sizing we własnych projektach, jednak należy także poamiętać o jasnym poinformowaniu innych developerów o tym rozwiązaniu, by niepotrzebnie nie zastanawiali się dlaczego coś nie działa lub wyświetla się inaczej, niż zakładali (np. zgodnie z wytycznymi W3C).

Należy pamiętać o wsparciu właściwości box-sizing i korzystaniu z przedrostków:

* {
-webkit-box-sizing: border-box; /* iOS <= 4 i Android <= 2.3 */
-moz-box-sizing: border-box; /* Firefox */
box-sizing: border-box; /* Chrome, Opera, Safari 5+ i IE 8+ */
}

Plusy:

  • O wiele łatwiej obliczyć wielkość danego lementu – szerokość będzie taka, jaką się zdefiniuje bez względu na border czy padding.
  • Można stosować procentowe szerokości kontenerów i jednocześnie jednostki em lub piksele dla paddingu. W tradycyjnym modelu trzeba by się posiłkować atrybutem calc() dla obliczania wartości i jednostką rem dla fontów.
  • Starsi developerzy mają już doświadczenie z IE6 i łatwo mogą wrócić do tego modelu.

Minusy:

  • IE7 i niższe to problem (na szczęście jest polyfill), a Firefox i starsze urządzenia mobilne muszą korzystać z przedrostków.
  • Nowe rozwiązania mogą nieść za sobą nowe problemy. W przypadku border-box pojawi się kwestia obliczania wymiarów samej zawartości kontenerów.

Podsumowanie

Wszystko zależy od developera i tego jak będzie mu wygodniej – oczywiście jeśli ma możliwość wyboru. Na pewno warto spróbować tego we własnym, prywatnym projekcie i zobaczyć czy przypadkiem taki model nie jest wygodniejszy w użyciu. Jeśli nie, to zawsze można wrócić do poprzedniego, rekomendowanego przez W3C.

Andrzej Mazur — front-end developer, bloger, HTML5 game developer, twórca CSS4.pl i FrontStart.pl. Pasjonat nowych, otwartych technologii.

komentarzy 6

  • Awatar
    Mr.Mr

    22 sierpnia 2012 11:05

    Osobiście od dawna stosuję border-box, jest to dużo wygodniejsze rozwiązanie

    Odpowiedz
  • Awatar
    Michał Kortas

    22 sierpnia 2012 13:04

    Ciekawy wpis Pana Andrzeja. Mam nadzieję, że jeszcze nie raz napisze gościnnie na łamach naszego wortalu :-)

    Odpowiedz
  • Awatar
    Andre

    29 października 2012 22:45

    Dziękuję, zwłaszcza link do polyfill – pozwolił mi zaoszczędzić mnóstwo czasu.

    Odpowiedz
  • Awatar
    Dominik Kucharski

    2 września 2013 14:37

    Od siebie dodam, że warto zastosować border-box także dla pseudoelementów before i after.
    *, *:before, *:after {
    […]
    }

    Odpowiedz
  • Awatar
    Paweł Czerski

    15 października 2013 01:21

    Artykuł podaje:
    Model pudełkowy IE6: szerokość = width (tzw. border-box)
    Model pudełkowy W3C: szerokość = width + padding + border

    — tylko że to właśnie ten drugi jest modelem border-box… Fatalne pomieszanie w punkcie, który rzecz powinien wyjaśniać.

    Odpowiedz
    • Awatar
      Mr.Mr

      15 października 2013 08:52

      Myślę, że to można akurat interpretować dwojako. Ja np. zrozumiałem to tak jak (wydaje mi się) zamierzał autor.

      Odpowiedz

Zostaw odpowiedź