Tot ce trebuie să știți despre marjele CSS

Publicat: 2022-03-10
Rezumat rapid ↬ Marjele în CSS par destul de simple la prima vedere. Aplicat unui element, formează un spațiu în jurul elementului, împingând celelalte elemente. Cu toate acestea, există mai mult la o marjă decât ați putea crede.

Unul dintre primele lucruri pe care cei mai mulți dintre noi le-am învățat când am învățat CSS, a fost detaliile diferitelor părți ale unei casete în CSS, descrise ca Modelul cutiei CSS. Unul dintre elementele din Modelul cutiei este marginea, o zonă transparentă în jurul unei cutii, care va împinge alte elemente departe de conținutul cutiei. Proprietățile margin-top , margin-right , margin-bottom și margin-left au fost descrise chiar înapoi în CSS1, împreună cu margin scurtă pentru setarea tuturor celor patru proprietăți simultan.

O marjă pare a fi un lucru destul de necomplicat, totuși, în acest articol, vom arunca o privire asupra unora dintre lucrurile care îi provoacă pe oameni în ceea ce privește utilizarea marjelor. În special, ne vom uita la modul în care marjele interacționează între ele și cum funcționează efectiv colapsul marjelor.

Modelul cutiei CSS

Ca și în cazul tuturor articolelor despre părți ale modelului CSS Box, ar trebui să definim ce înțelegem prin asta și cum modelul a fost clarificat prin versiunile CSS. Modelul cutiei se referă la modul în care diferitele părți ale unei cutii - conținutul, umplutura, chenarul și marginea - sunt așezate și interacționează între ele. În CSS1, Modelul Box a fost detaliat cu diagrama artistică ASCII prezentată în imaginea de mai jos.

ascii art desen al modelului cutie
Reprezentarea modelului CSS Box în CSS1

Cele patru proprietăți ale marjei pentru fiecare parte a casetei și prescurtarea margin au fost toate definite în CSS1.

Specificația CSS2.1 are o ilustrație pentru a demonstra modelul cutiei și, de asemenea, definește termenii pe care îi folosim în continuare pentru a descrie diferitele casete. Specificația descrie caseta de content box padding box , border box și margin box , fiecare fiind definită de marginile conținutului, de umplere, de chenar și, respectiv, de margine.

diagrama modelului CSS Box
Îndepărtarea modelului CSS Box în CSS2

Există acum o specificație de model de cutie de nivel 3 ca proiect de lucru. Această specificație se referă la CSS2 pentru definițiile modelului de cutie și a marjelor, prin urmare este definiția CSS2 pe care o vom folosi pentru cea mai mare parte a acestui articol.

Mai multe după săritură! Continuați să citiți mai jos ↓

Marja se prăbușește

Specificația CSS1, așa cum a definit marginile, a definit, de asemenea, că marginile verticale se prăbușesc . Acest comportament de prăbușire a fost sursa de frustrare legată de marjă de atunci. Prăbușirea marjelor are sens dacă luați în considerare că în acele zile de început, CSS era folosit ca limbaj de formatare de documentare. Restrângerea marjei înseamnă că, atunci când un titlu cu o marjă inferioară, este urmat de un paragraf cu o marjă superioară, nu veți obține un decalaj imens între acele elemente.

Când marginile se prăbușesc, ele se vor combina astfel încât spațiul dintre cele două elemente să devină cel mai mare dintre cele două margini. Marja mai mică terminând în esență în interiorul celei mai mari.

Marjele se prăbușesc în următoarele situații:

  • Frații alăturați
  • Cutii complet goale
  • Element părinte și primul sau ultimul element copil

Să aruncăm o privire pe rând la fiecare dintre aceste scenarii, înainte de a privi lucrurile care împiedică prăbușirea marjelor în aceste scenarii.

Frații alăturați

Descrierea mea inițială a colapsării marjelor este o demonstrație a modului în care marjele dintre frații adiacenți se prăbușesc. În afară de situațiile menționate mai jos, dacă aveți două elemente afișate unul după altul în flux normal, marginea de jos a primului element se va prăbuși cu marginea de sus a următorului element.

În exemplul CodePen de mai jos, există trei elemente div . Primul are o margine de sus și de jos de 50 de pixeli. Al doilea are o marjă de sus și de jos de 20 px. Al treilea are o marjă de sus și de jos de 3em. Marja dintre primele două elemente este de 50 de pixeli, deoarece marginea superioară mai mică este combinată cu marginea inferioară mai mare. Marja dintre al doilea element din 3em, deoarece 3em este mai mare decât cei 20 de pixeli din partea de jos a celui de-al doilea element.

Vedeți Pen [Margini: frați adiacente](https://codepen.io/rachelandrew/pen/OevMPo) de Rachel Andrew.

Vedeți Marginile stiloului: frații adiacente de Rachel Andrew.

Cutii complet goale

Dacă o casetă este goală, atunci marginile ei de sus și de jos se pot prăbuși una cu cealaltă. În următorul exemplu CodePen, elementul cu o clasă de gol are o marjă de sus și de jos de 50 de pixeli, cu toate acestea, spațiul dintre primul și al treilea element nu este de 100 de pixeli, ci de 50. Acest lucru se datorează colapsării celor două margini. Adăugarea de orice la acea casetă (chiar și umplutură) va face ca marginile de sus și de jos să fie utilizate și să nu se restrângă.

Vedeți Pen [Margini: casete goale](https://codepen.io/rachelandrew/pen/JQLGMr) de Rachel Andrew.

Vezi Marjele stiloului: cutii goale de Rachel Andrew.

Element Părinte și primul sau ultimul copil

Acesta este scenariul de colaps al marjei care prinde oamenii cel mai des, deoarece nu pare deosebit de intuitiv. În următorul CodePen, am un div cu o clasă de wrapper și i-am dat acel div un outline în roșu, astfel încât să puteți vedea unde este. Cele trei elemente secundare au toate o marjă de 50 de pixeli. Cu toate acestea, primul și ultimul articol sunt la același nivel cu marginile ambalajului; nu există o marjă de 50 de pixeli între element și înveliș.

Vedeți Pen [Margins: margin on first and last child](https://codepen.io/rachelandrew/pen/BgrKGp) de Rachel Andrew.

Vezi Marjele stiloului: marja pe primul și ultimul copil de Rachel Andrew.

Acest lucru se datorează faptului că marja de pe copil se prăbușește cu orice marjă de pe părinte ajungând astfel în exteriorul părintelui. Puteți vedea acest lucru dacă inspectați primul copil folosind DevTools. Zona galbenă evidențiată este marginea.

Elementul cu o marjă evidențiată galbenă care apare în afara părintelui
DepvTools vă poate ajuta să vedeți unde ajunge marja dvs

Numai Block Margins Collapse

Ultimul exemplu evidențiază și ceva despre prăbușirea marjelor. În CSS2, doar marginile verticale sunt specificate pentru a se restrânge - adică marginile de sus și de jos ale unui element dacă sunteți într-un mod de scriere orizontală. Deci, marginile din stânga și din dreapta de mai sus nu se prăbușesc și nu se termină în afara învelișului.

Notă : Merită să ne amintim că marginile se prăbușesc doar în direcția blocului, cum ar fi între paragrafe.

Lucruri care împiedică prăbușirea marjei

Marjele nu se restrâng niciodată dacă un articol are o poziționare absolută sau este flotat. Cu toate acestea, presupunând că ați întâlnit unul dintre locurile în care marginile se prăbușesc descrise mai sus, cum puteți opri colapsul acestor margini?

Primul lucru care încetează să se prăbușească sunt situațiile în care există ceva între elementele în cauză.

De exemplu, o casetă complet goală de conținut nu își va restrânge marginile de sus și de jos dacă are un chenar sau o umplutură aplicată. În exemplul de mai jos am adăugat 1px de umplutură în casetă. Acum există o marjă de 50 de pixeli deasupra și sub casetă.

Vezi stiloul [Margini: cutiile goale cu umplutură nu se restrâng](https://codepen.io/rachelandrew/pen/gNeMpg) de Rachel Andrew.

Vedeți Marginile stiloului: cutiile goale cu umplutură nu se prăbușesc de Rachel Andrew.

Acest lucru are o logică în spate, dacă cutia este complet goală, fără margini sau umplutură, este în esență invizibilă. Poate fi un element de paragraf gol aruncat în marcaj de CMS. Dacă CMS-ul dvs. adăuga elemente de paragraf redundante, probabil că nu ați dori ca acestea să creeze decalaje mari între celelalte paragrafe din cauza respectării marjelor lor. Adăugați orice în cutie și veți obține acele goluri.

Comportament similar poate fi observat cu marje pe primul sau ultimul copil care se prăbușește prin părinte. Dacă adăugăm un chenar la părinte, marginile copiilor rămân în interior.

Vedeți Pen [Margini: marja de pe primul și ultimul copil nu se prăbușește dacă părintele are o chenar](https://codepen.io/rachelandrew/pen/vqRKKX) de Rachel Andrew.

Vedeți Marjele stiloului: marja de pe primul și ultimul copil nu se prăbușește dacă părintele are o chenar de Rachel Andrew.

Încă o dată, comportamentul are o anumită logică. Dacă aveți elemente de împachetare în scopuri semantice care nu se afișează vizual, probabil că nu doriți ca acestea să introducă lacune mari în afișaj. Acest lucru avea foarte mult sens atunci când web-ul era în mare parte text. Este mai puțin util ca comportament atunci când folosim elemente pentru a așeza un design.

Crearea unui context de formatare a blocurilor

Un nou context de formatare a blocurilor (BFC) va preveni, de asemenea, colapsul marginii prin elementul care îl conține. Dacă ne uităm din nou la exemplul primului și ultimului copil, ajungând cu marginile în afara învelișului, și dăm display: flow-root , creând astfel un nou BFC, marginile rămân în interior.

Vedeți Pen [Margins: a new Block Formatting Context contains margins](https://codepen.io/rachelandrew/pen/VJXjEp) de Rachel Andrew.

Vedeți Marginile stiloului: un nou context de formatare a blocurilor conține margini de Rachel Andrew.

Pentru a afla mai multe despre display: flow-root , citiți articolul meu „Înțelegerea aspectului CSS și a contextului de formatare a blocurilor”. Schimbarea valorii proprietății overflow în auto va avea același efect, deoarece aceasta creează și un nou BFC, deși poate crea și bare de defilare pe care nu le-ați dorit în unele scenarii.

Containere Flex și Grid

Containerele Flex și Grid stabilesc contexte de formatare Flex și Grid pentru copiii lor, astfel încât aceștia au un comportament diferit pentru a bloca aspectul. Una dintre aceste diferențe este că marjele nu se prăbușesc:

„Un container flexibil stabilește un nou context de formatare flexibil pentru conținutul său. Acest lucru este același cu stabilirea unui context de formatare bloc, cu excepția faptului că este utilizat aspectul flexibil în loc de aspectul bloc. De exemplu, flotoarele nu intră în containerul flexibil, iar marginile containerului flexibil nu se prăbușesc odată cu marginile conținutului său.”

- Flexbox Nivelul 1

Dacă luăm exemplul de mai sus și transformăm ambalajul într-un container flexibil, afișând articolele cu flex-direction: column , puteți vedea că marginile sunt acum conținute de ambalaj. În plus, marjele dintre elementele flexibile adiacente nu se prăbușesc unele cu altele, așa că ajungem la 100 de pixeli între elementele flexibile, totalul celor 50 de pixeli din partea de sus și de jos a articolelor.

Vedeți Pen [Margins: margins on flex items not collapse](https://codepen.io/rachelandrew/pen/mZxreL) de Rachel Andrew.

Vedeți Marjele stiloului: marjele articolelor flexibile nu se prăbușesc de Rachel Andrew.

Strategii de marjă pentru site-ul dvs

Din cauza prăbușirii marjelor, este o idee bună să veniți cu un mod consecvent de a trata marjele pe site-ul dvs. Cel mai simplu lucru de făcut este să definiți marginile doar în partea de sus sau de jos a elementelor. În acest fel, nu ar trebui să întâmpinați prea des probleme de prăbușire a marjelor, deoarece partea cu o marjă va fi întotdeauna adiacentă unei părți fără marjă.

Notă : Harry Roberts are o postare excelentă care detaliază motivele pentru care setarea marjelor doar într-o singură direcție este o idee bună, și nu doar din cauza rezolvării problemelor de marjă care se prăbușesc.

Această soluție nu rezolvă problemele pe care le-ați putea întâlni cu marjele copiilor care se prăbușesc prin părintele lor. Această problemă particulară tinde să fie mai puțin frecventă și știind de ce se întâmplă, vă poate ajuta să găsiți o soluție. O soluție ideală pentru aceasta este să oferiți componentelor care necesită display: flow-root , ca alternativă pentru browserele mai vechi, puteți utiliza overflow pentru a crea un BFC, a transforma părintele într-un container flexibil sau chiar a introduce un singur pixel de umplutură. Nu uitați că puteți utiliza interogări de caracteristici pentru a detecta suportul pentru display: flow-root astfel încât numai browserele vechi primesc o soluție mai puțin optimă.

De cele mai multe ori, constat că a ști de ce marjele se prăbușesc (sau nu) este cheia. Puteți apoi să vă dați seama de la caz la caz cum să faceți față. Indiferent ce alegeți, asigurați-vă că împărtășiți acele informații cu echipa dvs. Destul de des, prăbușirea marginii este puțin misterioasă, așa că motivul pentru care faceți lucruri pentru a o contracara poate să nu fie evident! Un comentariu în codul dvs. ajută foarte mult - puteți chiar să trimiteți la acest articol și să ajutați la împărtășirea cunoștințelor despre colapsul marjei.

M-am gândit că voi completa acest articol cu ​​alte câteva informații legate de marjă.

Marje procentuale

Când utilizați un procent în CSS, acesta trebuie să fie un procent din ceva. Marginile (și umplutura) setate folosind procente vor fi întotdeauna un procent din dimensiunea în linie (lățimea într-un mod de scriere orizontală) a părintelui. Aceasta înseamnă că veți avea o umplutură de dimensiuni egale în jurul elementului atunci când utilizați procente.

În exemplul CodePen de mai jos, am un înveliș care are 200 de pixeli lățime, în interior este o cutie care are o marjă de 10%, marja este de 20 de pixeli pe toate părțile, adică 10% din 200.

Vedeți Pen [Margini: marje procentuale](https://codepen.io/rachelandrew/pen/orqzrP) de Rachel Andrew.

Vedeți Marjele stiloului: marje procentuale de Rachel Andrew.

Marjele într-o lume relativă a fluxului

Am vorbit despre marjele verticale de-a lungul acestui articol, cu toate acestea, CSS modern tinde să gândească lucrurile într-un flux relativ, mai degrabă decât într-un mod fizic. Prin urmare, atunci când vorbim despre margini verticale, vorbim cu adevărat despre marje în dimensiunea blocului. Aceste margini vor fi de sus și de jos dacă suntem într-un mod de scriere orizontală, dar ar fi dreapta și stânga într-un mod de scriere verticală scris de la stânga la dreapta.

Odată ce se lucrează cu direcții logice, relative ale fluxului, devine mai ușor să vorbim despre începutul blocului și sfârșitul blocului, mai degrabă decât de sus și de jos. Pentru a face acest lucru mai ușor, CSS a introdus specificația Logical Properties and Values. Aceasta mapează proprietățile relative ale fluxului pe cele fizice.

Pentru margini, acest lucru ne oferă următoarele mapări (dacă lucrăm în limba engleză sau în orice alt mod de scriere orizontală cu o direcție a textului de la stânga la dreapta).

  • margin-top = margin-block-start
  • margin-right = margin-inline-end
  • margin-bottom = margin-block-end
  • margin-left = margin-inline-start

Avem, de asemenea, două scurtări noi care permit setarea ambelor blocuri simultan sau ambele în linie.

  • margin-block
  • margin-inline

În următorul exemplu CodePen, am folosit aceste cuvinte cheie relative de flux și apoi am schimbat modul de scriere al casetei, puteți vedea cum marginile urmează direcția textului, mai degrabă decât să fie legate de sus, dreapta, jos și stânga fizic.

Vedeți Pen [Margins: flow relative margins](https://codepen.io/rachelandrew/pen/BgrQRj) de Rachel Andrew.

Vedeți Marjele stiloului: marjele relative ale fluxului de Rachel Andrew.

Puteți citi mai multe despre proprietățile și valorile logice pe MDN sau în articolul meu „Înțelegerea proprietăților și valorilor logice” aici pe Smashing Magazine.

Pentru a încheia

Acum știi cele mai multe despre ce trebuie să știi despre marje! În scurt:

  • Prăbușirea marjei este un lucru. Înțelegerea de ce se întâmplă și când nu te va ajuta să rezolvi orice probleme pe care le poate cauza.
  • Setarea marjelor într-o singură direcție rezolvă doar multe dureri de cap legate de margine.
  • Ca în orice în CSS, împărtășiți echipei dvs. deciziile pe care le luați și comentați codul.
  • Gândirea la dimensiunile bloc și în linie, mai degrabă decât la cele fizice de sus, dreapta, jos și stânga, vă va ajuta pe măsură ce web-ul se îndreaptă spre modul de scriere agnostic.