Jak funguje CSS Box Model
Věděli jste, že existuje mezinárodní den box-sizingu? Vlastnosti padding, border a margin sice nejsou raketová věda, ale některé jejich kombinace a chování v určitých situacích dokáží zamotat hlavu i zkušeným kodérům. Pojďme si proto připomenout definici těchto základních stavebních prvků CSS.
Základ rozložení obsahu na webu je zakořeněn v box modelu. Ten popisuje obdélníková pole, která jsou generována pro všechny prvky ve stromu dokumentu (DOM). Tento jev má na starost vykreslující modul prohlížeče.
Můžeme vlastně brát jako fakt, že každý HTML element v dokumentu je obdélník – tedy box. Jak je vidět na obrázku, obsah (content) je obalen třemi oblastmi, které mají dané pořadí a jejichž vlastnosti je možné měnit s pomocí CSS: padding, border a margin.
Tyto oblasti jsou vždy součástí každého prvku v dokumentu, i když nejsou ve stylopisu definovány. V tu chvíli mají nulové, respektive žádné hodnoty.
Každé z těchto vlastností včetně obsahu (content) můžeme nastavit rozměr, typ, pozicování, vztah k jiným elementům nebo přidat externí informaci.
Jednotlivé oblasti
Jednotlivé oblasti lze stručně popsat.
Content
Uvnitř ohraničení této oblasti se nachází vlastní obsah prvku. Může to být text, obrázek, video nebo jakýkoliv jiný element v dokumentu. Jak šířku, tak výšku udává velikost obsahu. S obsahem lze manipulovat pouze v případě pseudo elementů.
Padding
Vnitřní okraj prvku (padding) vyhrazuje prostor okolo obsahové oblasti (content) až po oblast ohraničení (border). Padding je tedy odsazení uvnitř prvku samotného.
Border
Jedná se o ohraničení prvku (border), které se nachází mezi oblastí vnitřního okraje (padding) a vnějšího okraje (margin). Používá se k dekoraci ohraničení a je možné tuto oblast vizuálně upravovat a nastavovat její podobu.
Margin
Tato oblast vnějšího okraje (margin) rozšiřuje prostor okolo prvku, počínaje prostorem od ohraničení (borderu). Jedná se o prázdný prostor, který se používá k oddělení jednoho prvku od druhého.
Jak rozlišit a používat jednotlivé oblasti
U oblasti content nebo border dojde málokdy k záměně. V prvním případě jde o obsah prvku a v druhém o jeho ohraničení. Často ale vzniká nepochopení v použití vnitřního a vnějšího odsazení.
Obě vlastnosti (padding i margin) slouží k vytváření prázdného prostoru kolem obsahu prvků a může být proto snadné je zaměnit nebo nebrat jejich rozdílné chování v potaz. Rozdíl je v metodě, jakou se mezery vytváří a k jakému použití slouží.
Padding
Padding neboli vnitřní odsazení nám definuje, jakou vzdálenost si má prvek vymezit mezi obsahem (content) a ohraničením (border). Využívá se pro odsazení prvků v kontejnerech, pro vnitřní odsazení textu u prvků s nastaveným pozadím nebo pro zvětšení prvku samotného – např. u tlačítek.
p {
padding: 10px;
}
Margin
Margin neboli vnější odsazení je osobní prostor prvku. Margin se využívá v případech, kdy chceme mít kolem prvku prázdný prostor – požadujeme, aby se prvek odsadil od těch okolních. Využití může také najít pro zarovnání uvnitř elementu ve vertikálním a horizontálním směru (hodnota auto
). A na rozdíl od všech předchozím vlastností, margin nemá efekt na rozměry box modelu.
p {
margin: 10px;
}
Margin má navíc i další specifické chování: jeho vertikální hodnoty se v určitých případech slučují. Tomuto chování se říká margin collapsing.
Margin collapsing
Margin neboli vnější okraj má oproti vnitřnímu okraji (paddingu) jedno specifické chování. Pro toto chování existuje v angličtině spojení margin collapsing. Do češtiny bychom to mohli přeložit jako slučování okrajů.
Kdy ke slučování dochází
Definujme si, kdy k tomuto chování dochází. Sloučení vnějších okrajů dvou elementů nastane v případě, že jsou splněny tyto podmínky:
- jedná se o blokové elementy,
- jedná se o horní nebo dolní okraje (na horizontální okraje se sloučení neaplikuje),
- elementy se ve struktuře nachází ve stejné úrovni struktury DOM a neleží mezi nimi žádný oddělující obsah, nebo jsou elementy ve vztahu rodič – potomek a mají definováno vnitřní odsazení nebo ohraničení,
- na prvek není aplikována vlastnost
float
, - prvky nemají nastavené absolutní pozicování.
Na stránce MDN najdete ještě podrobnější popis případů, kdy ke slučování dochází.
Proč ke slučování dochází
Slučování je navrženo tak, aby bylo snadné definovat vertikální okraje pro více elementů jdoucích v obsahu za sebou.
Toto chování se hodí například při návrhu blogového článku, kde jsou umístěny různé prvky, u kterých chceme mít sjednocené odsazení. Obrázky, tabulky, nadpisy, odstavce a další elementy tak mohou mít stejné vnější odsazení bez ohledu na to, v jakém pořadí jdou za sebou. Díky tomu nemusíme definovat odsazení pro jednotlivé kombinace.
Jak slučování funguje
Stručně můžeme říct, že ke sloučení okrajů dochází, pokud se dva vertikální okraje (horní a dolní) dostanou do vzájemného kontaktu. Potom dochází ke sloučení a je aplikována pouze větší hodnota odsazení. Můžeme si to představit jako souboj dvou vnějších okrajů, kde vyhrává ten, který je větší:
Pokud jsou hodnoty odsazení u obou prvků stejné, zůstane pouze jeden, respektive se obě hodnoty sloučí do jedné:
Převaha odsazení rodičovského prvku
Ke sloučení taky dochází u prvků, kde má jejich nadřazený element definován vnější okraj ve svislém směru stejně tak jako prvky uvnitř. V tomto případě ale záleží, jaké mají prvky uvnitř vlastnosti.
Pokud mají prvky uvnitř rodičovského elementu nastavenou vlastnost vnitřního okraje (padding) nebo ohraničení (border), vnější odsazení se nebude slučovat. Prohlédněte si příklad na CodePen, kde je u vnořených elementů nastaveno vnitřní odsazení:
See the Pen Box Model: Collapsing Margins - Parents and Children Comparison by Ondřej Konečný (@ondrejko) on CodePen.
Záporné hodnoty
U záporných hodnot vnějšího odsazení funguje slučování stejně. Musíme si jen dát pozor na výpočet.
Pokud je jedna hodnota vnějšího odsazení záporná, odečte se od kladné hodnoty. Pokud máme tedy nastaveno dolní odsazení (margin-bottom
) na -50px
a následuje prvk s horním odsazením (margin-top
) 100px
, výsledná hodnota odsazení bude po sloučení 50px
. Tento příklad si můžete opět vyzkoušet na CodePen.
See the Pen Box Model: Collapsing Margins - Vertical and Negative by Ondřej Konečný (@ondrejko) on CodePen.
Stejný princip se použije i v případě, kdy slučujeme dvě záporná odsazení. Opět se po sloučení aplikuje vyšší (v tomto případě „zápornější“ nebo lépe absolutní) hodnota.
Box Sizing
box-sizing
neboli vlastnost, která definuje způsob výpočtu šířky (width
) a výšky (height
) prvku, je v prohlížečích defaultně nastavena na hodnotu content-box
. Existuje však ještě jedna hodnota, která mění chování výpočtu velikosti prvku: border-box
. Historicky se ve specifikaci objevila také hodnota padding-box
, která ale byla časem odebrána a v dnešní specifikaci již neexistuje. Ta počítala velikost boxu součtem oblastí content a padding, tedy bez rámečku – border.
Content-Box
Výpočet šířky a výšky prvku je dán součtem oblastí content, padding a border. Vlastnost margin nemá vliv na výslednou velikost jednotlivých prvků.
Znamená to, že pokud je nastavena šířka a výška prvku, hodnoty vlastností padding a border nám rozšíří celkovou velikost boxu o jejich hodnoty. Toto chování odpovídá nastavení CSS vlastnosti box-sizing: content-box
.
See the Pen Box Model: Content-Box by Ondřej Konečný (@ondrejko) on CodePen.
Border-Box
U tohoto typu modelu se definovaná šířka a výška rovná výsledné velikosti boxu, a to bez ohledu na hodnoty vlastností padding
nebo border
. Vlastnost margin
opět nemá vliv na výslednou velikost prvku. Toto chování odpovídá nastavení CSS vlastnosti box-sizing: border-box
.
See the Pen Box Model: Border-Box by Ondřej Konečný (@ondrejko) on CodePen.
Nastavení box modelu
V dnešní době se ukazuje nastavení jednotného box modelu pro všechny elementy jako nejlepší možné řešení. A je pro to jednoduché vysvětlení. Se všemi prvky na webu se pracuje stejně, a tak je jejich chování napříč celým dokumentem konzistentní.
Navíc nástroje pro tvorbu webového designu pracují s jednotlivými prvky stejně, což usnadňuje spolupráci mezi designerem a kodérem. Dekorace jako rámečky neovlivňují definované rozměry prvků a stejně tak by se měly chovat i prvky na výsledném webu.
Doporučené bývá nastavení vlastnosti box-sizing
na hodnotu border-box
. To je přímočaré a intuitivní, ovšem toto pravidlo musíme ve stylopisu nastavit ručně, protože kvůli zpětné kompatibilitě stále zůstává výchozím nastavením hodnota content-box
.
Existují však výjimky, kdy se pro vlastnost box-sizing
doporučuje nastavit hodnotu content-box
. Toto nastavení nám u relativního nebo absolutního pozicování zaručí, aby byly hodnoty pro nastavení pozicování relativní k obsahu, nezávislé na změnách rámečku nebo odsazení.
Do základního stylopisu se tak přidává následující pravidlo, které je dnes již běžnou praxí:
*, *::before, *::after {
box-sizing: border-box;
}
Jon Neal přišel s jistou alternativou, která se zdá být také k zamyšlení. Namísto resetování vlastnosti box-sizing
na border-box
u všech prvků ji nastavuje jen kořenovému prvku dokumentu. Pro ostatní prvky využívá hodnotu inherit
, která umožní vlastnost box-sizing
zdědit:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
Může se to hodit v případě, kdy navrhneme komponentu, u které předpokládáme chování výchozího nastavení box-sizing: content-box
, stejně tak jako u prvků vložených uvnitř. Tím můžeme zamezit nežádoucímu rozbití vnořených komponent.
Shrnutí
Chování box modelu je díky svému vývoji trochu matoucí. Dokazuje to i fakt, že k 1. únoru vznikl International box-sizing Awareness Day – tedy mezinárodní den povědomí o box-sizing
vlastnosti CSS Box Modelu.
Výchozí nastavení prohlížečů má kvůli zpětné kompatibilitě nastavenou vlastnost box-sizing
na content-box
, i když je dnes v drtivé většině využívána hodnota border-box
. Neměli bychom proto zapomenout na definování chování box modelu v našem stylopisu, stejně tak jako na pochopení rozdílů mezi těmito hodnotami.
Je dobré zmínit, že je na každém jedinci, zdali bude využívat jedné, či druhé metody výpočtu. Spíše je důležité pochopit principy fungování a využívat je tam, kde se nám hodí. Každá metoda má své klady i zápory.
Související odkazy
Další články od autora:
Sdílejte
Líbí se vám článek? Podpořte jej sdílením!
Komentujte
Chcete k článku něco doplnit? Našli jste chybu? Napište e-mail.