FrontEnd.ro logo

Box model

logistics

Până acum, am învățat ce înseamnă CSS, la ce îl putem folosi, și, foarte important, cum să îl folosim. CSS este un limbaj cu care putem crea site-uri cu un design excelent. La bază, fiecare element e doar un dreptunghi cu câteva proprietăți mai speciale.

În această lecție vom învăța despre box-model: din ce este compus și cum este folosit “în spate” pentru a crea acele design-uri WOW. Înțelegerea modului în care lucrează este cheia care te va ajuta să construiești orice interfață și să rezolvi diverse probleme de layout ce pot apărea.

#Componentele Box Model

Box model este compus din 4 proprietăți:

  • Content: Conținutul "cutiei", adică locul unde se afișează textul / imaginea / etc.
  • Padding: Un spațiu transparent care înconjoară conținutul
  • Border: O "bordură" care înconjoară conținutul și padding-ul
  • Margin: O suprafață transparentă din afara border-ului care ajută la spațierea dintre elemente
Box Model vizualizat - MDN
Box Model vizualizat - MDN

În mod normal, dacă nu intervenim, majoritatea elementelor ar fi lipite unul de celălalt. Browserele aplică totuși câteva margini pe anumite elemente, în special pe tag-urile de tip heading (<h1> - <h6>) și pe paragrafe (<p>), dar nu vom intra acum în detaliu.


<div>Element</div>
<div>Element</div>
            
Doua elemente fara spatieri
Doua elemente fara spatieri

Așa cum se poate observa, ambele tag-uri <div> sunt lipite. Nu avem o spațiere definită, și nici vreo bordură pentru a le separa. Haideți să vedem cum putem folosi componentele box model-ului pentru a schimba modul în care cele două <div> -uri sunt afișate.

#Border

Vom începe cu border. Border nu va adăuga spațiere propriu-zisă între elemente, însă va ajuta la setarea unor limite vizuale pentru acestea.

div {
  border: 1px solid #000;
}            
Doua elemente cu border atribuit
Doua elemente cu border atribuit

Setarea unui border pentru cele două div-uri ajută puțin la separare, însă elementele tot lipite sunt. Este departe de acel design WOW pe care îl dorim. Pentru a le distanța, putem folosi margin.

#Margin


div {
  border: 1px solid #000;
  margin: 12px;
}             
Doua elemente cu margin
Doua elemente cu margin

Deja putem vedea o îmbunătățire. Cele două div-uri nu mai sunt lipite, ci au puțin spațiu între ele, 12px mai exact.

Chiar dacă am setat 12px ca margin pentru ambele <div>-uri, distanța dintre cele două elemente nu va fi 24px (12px * 2), ci va rămâne 12px. Acest lucru se întâmplă din cauza conceptului numit margin collapsing. Este un fenomen care ar merita propria mini-lecție, însă ceea ce trebuie să știi pentru moment este că uneori două margini se pot combina într-una singură, care va avea valoarea maximă dintre cele două margini individuale. Poți citi mai multe aici.

Dacă deschidem DevTools și inspectăm unul dintre <div>-uri, vom vedea imaginea de mai jos. Concret, chenarul portocaliu reprezintă de fapt marginea pe care noi am setat-o în cod, adică 12px în toate direcțiile (top, right, bottom, left).

DevTools deschis in modul inspect
DevTools deschis in modul inspect

#Padding

Padding-ul este folosit pentru a adăuga spațiu între content și border. În exemplul nostru, padding-ul s-ar afișa între cuvântul "Element" și bordura neagră de 1px pe care noi am setat-o prima dată.

div {
  border: 1px solid #000;
  margin: 12px;
  padding: 8px;
}            
Element cu padding aplicat
Element cu padding aplicat

Chenarul verde este echivalentul padding-ului de 8px setat. După cum se poate observa, cuvântul "Element" este acum mai distanțat față de bordură.

#DevTools Box Model

Ok, acum că am învățat despre border, margin și padding, este momentul să vedem cum se aplică toate pe elementul din exemplu. Pentru asta, vom folosi din nou DevTools.

Element cu toate componentele box model vizibile
Element cu toate componentele box model vizibile
Acelasi element vazut in DevTools
Acelasi element vazut in DevTools

Prima imagine ar trebui să vă fie familiară. Acolo veți regăsi elementul îmbunătățit vizual cu reprezentarea grafică a tuturor proprietăților ce compun box model-ul.

În imaginea a doua, veți vedea exact dimensiunile setate pentru margin, border și padding. Chenarul albastru este corespondentul content-ului, care în exemplu are o lățime de 372px și o înălțime de 19px.

Haideți să setăm și proprietățile width și height, pentru a le vedea modificate și în reprezentarea grafică.

div {
  border: 1px solid #000;
  margin: 12px;
  padding: 8px;
  width: 100px;
  height: 50px;
}               
Box Model complet, vizualizat in DevTools
Box Model complet, vizualizat in DevTools

Ok, acum am setat toate valorile unui box model. Putem observa asta și pe elementul din pagină.

Box Model complet, vizualizat pe pagina
Box Model complet, vizualizat pe pagina

Hmm, ceva nu e bine. Am setat lățimea de 100px și înălțimea de 50px , însă div-ul nostru are în schimb o lățime de 118px și o înălțime de 68px. Oare de ce?

#Box-sizing

Pentru a înțelege ce s-a întâmplat, trebuie să vorbim puțin despre proprietatea box-sizing.

Această proprietate controlează modul în care este calculată dimensiunea totală a unui element (lățime și înălțime).

În CSS, dacă setam o lățime de 100px, ea se va aplica asupra content-ului. În momentul în care adăugăm padding sau border, aceste valori se vor adăuga la dimensiunea totală a elementului final care va fi randat pe pagină.

Hai să ne întoarcem la exemplul nostru. Ne vom concentra atenția asupra lățimii, întrucât înălțimea are același mod de calcul.

div {
  border: 1px solid #000;
  margin: 12px;
  padding: 8px;
  width: 100px;
  height: 50px;
}               

Avem setat un width: 100px, un padding: 8px și un border: 1px. Modul în care este calculată lățimea este următorul:

100px + 8px * 2 + 1px * 2 = 118px

De ce 8px * 2? Trebuie să luăm în considerare padding-left și padding-right. Același lucru este valabil și pentru border.

Se poate observa că nu este neapărat un mod ușor de a seta dimensiuni. Dacă avem nevoie de o anumită lățime, trebuie să ne gândim la ce border și ce padding vom seta, pentru a reuși să ajungem la rezultatul dorit. Asta nu sună prea bine, nu?

Din fericire, CSS ne oferă o soluție: proprietatea box-sizing. Implicit, această proprietate are valoarea content-box, adică width-ul și height-ul se vor aplica asupra content-ului.

Cealaltă valoare este border-box. Setarea acestei valori îi va spune browser-ului să țină cont pentru calcularea dimensiuni de orice border sau padding adăugat. Content-ul va fi micșorat pentru a se putea atinge width-ul sau height-ul setat.

În imaginile de mai jos putem vedea exact aceste diferențe de la nivelul content-ului.

Element cu box-sizing: content-box, vedere din DevTools
Element cu box-sizing: content-box, vedere din DevTools
Element cu box-sizing: border-box, vedere din DevTools
Element cu box-sizing: border-box, vedere din DevTools

Diferența este vizibilă și în pagină, unde elementele sunt randate în forma finală, după ce toate calculele au fost făcute.

Sus -> border-box, jos -> content-box
Sus -> border-box, jos -> content-box

#Box Model interactiv

Ok, gata cu vorba. Hai să trecem și la ceva practic.

Mai jos, am recreat box model-ul din DevTools, pentru că tu să poți interacționa cu el și pentru a vedea în timp real cum este afectată dimensiunea elementului în funcție de valoarea proprietății box-sizing.

Valorile implicite setate în stânga servesc drept limite maxime, pentru a nu strica layout-ul general al paginii. Pentru a interacționa cu valorile, este suficient să setați orice valoare pozitivă mai mică decât acest maxim. La schimbarea checkbox-ului activ, ar trebui să vedeți valoarea finală modificată în funcție de alegerea voastră.

Content

Lățimea și înălțimea finală: 295px

Am acoperit destul de multă teorie în această lecție. Sper că acum este puțin mai clar cum este folosit box model in CSS. Dacă totuși consideri că ai nevoie de ceva mai multe informații, poți folosi una dintre resursele de mai jos:

Resurse suplimentare

  1. Documentația completă a box model-ului pe MDN
  2. Documentația completă a proprietății box-sizing pe MDN

Ai vreo sugestie de îmbunătățire a acestei lecții? Contribuie pe GitHub