CSS primește un rap rău pentru că nu se comportă așa cum se așteaptă oamenii. Unul dintre lucrurile care îi îndepărtează cel mai mult pe oameni sunt marjele. Pare atât de simple, dar au potențialul de a provoca probleme cu adevărat ciudate.

Pentru oamenii care tocmai intră în CSS, este cu ușurință unul dintre acele lucruri care te pot determina să gândești „acesta este un limbaj prost care nu are sens!”

Îl văd în fiecare zi – atât în ​​sala de clasă, cât și oamenii încearcă să-și dea seama de problemele lor de spațiu, precum și în problemele mele YouTube secțiuni de comentarii, de asemenea.

Într-un fel, marginile sunt un mic microcosmos al CSS în general. CSS pare atât de simplu cu property: value perechi, dar pe măsură ce progresați cu el, vă dați seama că se întâmplă multe.

Marginile par, de asemenea, atât de simple. Adăugați o marjă și adăugați spațiu gol în jurul acelui element. Dar, dintr-o dată, se comportă puțin diferit într-o situație decât în ​​alta, sau adăugați unele margin-top la un element copil și, în schimb, este părintele care se deplasează în jos.

Se produce frustrare.

În acest articol, sper să fac puțină lumină asupra modului în care funcționează marginile. Vom analiza unele dintre problemele obișnuite care apar, precum și soluții simple la aceste probleme.

Pentru a trece peste toate acestea, voi folosi exemple din Bootcamp responsive de proiectare web pe Scrimba, din care am extras acest aspect simplu din:

Aspect CSS folosind margini și padding

Care sunt marjele oricum?

Înainte de a intra cu adevărat în profunzimea de aici, vreau să mă asigur că știm cu toții ce sunt de fapt marjele!

Voi presupune că știm cu toții că marginile fac parte din modelul cutiei, marginea fiind completă la exterior, urmând conținutul în sine, umplutura și marginea.

MDN le explică foarte bine (accentul meu):

Marja este stratul cel mai exterior, înfășurând conținutul, umplutura și marginea ca spațiu alb între această casetă și alte elemente. Dimensiunea sa poate fi controlată folosind marjă și proprietăți conexe.

Cu alte cuvinte, este efectiv spațiu gol pe care îl putem folosi pentru a crea spațiu între o cutie și alta în aspectul nostru.

Gestionarea foilor de stil agent-utilizator

Browserele au în mod implicit o cantitate surprinzătoare de CSS, pe care o numim foi de stil agent-utilizator. Aceste stiluri sunt motivul pentru care, fără CSS din partea noastră, un <h1> este mai mare decât un <h2>, și de ce <body> are o marjă pe care tindem să o eliminăm întotdeauna.

Aceste stiluri sunt importante, dar conduc și la una dintre cele mai mari probleme cu care oamenii se confruntă cu marje! Marjele nu sunt implicite 0 pe toate elementele noastre, iar acest lucru poate provoca tot felul de probleme ciudate pe care le vom explora în scurt timp.

Listele, citatele bloc, paragrafele și titlurile au toate margin pe ele (printre alte elemente). Deși uneori sunt doar un ușor inconvenient, marja implicită a paragrafelor și a anteturilor pare a fi cea care provoacă cele mai multe probleme din cutie.

În mod implicit, marginile stânga și dreapta ale unui element de text sunt setate la 0, dar toate vin cu un margin-top și margin-bottom.

De multe ori le spun oamenilor că acele valori implicite de sus și de jos sunt aproximativ aceleași ca și font-size din acel element, deoarece este adevărat pentru <p> precum și <h3> prin <h6>. Pentru <h1> este de fapt 0.67em si pentru <h2> este 0.83em.

Aceasta înseamnă că există spațiu între elementele de pe pagina noastră, chiar dacă nu am stabilit în mod explicit o marjă.

Vom reveni la aceste valori implicite într-o secundă.

Prăbușirea marjelor

Marginile care se prăbușesc sunt de unde încep adesea durerile de cap.

Când două elemente au vertical marginile care se ating, se îmbină efectiv între ele.

Este deja un comportament ciudat, apoi îl adăugăm la faptul că este doar pentru margini verticale (sus și jos), am de ce oamenii se confundă și se enervează de ei.

Putem vedea acest lucru în acțiune cu următorul exemplu:

p {
  font-size: 18px;
  margin-bottom: 40px;
}

.links {
  margin-top: 40px;
}

Pentru a ilustra ceea ce se întâmplă aici, .links clasa este pe ultimul paragraf (<p class="links">), care conține cele două link-uri din interiorul său.

Când oamenii fac așa ceva, se așteaptă ca marja dintre paragraful din mijloc și linkurile de sub acesta să fie de 80 px (40px + 40px), dar în realitate este de 40 px. Cele două margini se ating una de cealaltă, așa că se îmbină una în cealaltă.

Paragraf și legături cu 40px spațiu între

Pentru a-l împinge și mai mult, să-i dăm pe al nostru <p>s ‘a margin-bottom la 100px:

p {
  font-size: 18px;
  margin-bottom: 100px;
}

.links {
  margin-top: 40px;
}

Din nou, cele două margini nu se adună împreună, se prăbușesc una în cealaltă, deci spațiul total aici este 100px.

Paragraf și legături cu spațiu de 100 px între

Ăsta este un lucru bun

În astfel de cazuri, este de fapt un lucru bun. Dacă există mai multe elemente cu margini diferite, nu este nevoie să adăugați marginile împreună pentru a vedea cât de mare este decalajul dintre elemente, deoarece ne putem baza pe faptul că marja mai mare câștigă întotdeauna.

De multe ori nici nu ne gândim la asta, funcționează doar așa cum ne așteptăm să funcționeze.

Când nu este un lucru bun

Acestea fiind spuse, un caz în care colapsul marginii provoacă tot felul de confuzii este atunci când primul copil dintr-un element are un margin-top care fuzionează cu cea a părintelui margin-top.

Să ne uităm la aceeași captură de ecran din nou:

Paragraf și legături cu spațiu de 100 px între

Există un spațiu alb între partea de sus a ferestrei și caseta neagră. Aceasta nu este din corp (este mult mai mare decât 8px marja pe care ar avea-o corpul).

Vrei să ghicești de unde vine?

De fapt vine din <h1> în partea de sus a acelei cutii negre.

Amintiți-vă când am menționat că folii de stil user-agent pot face unele lucruri ciudate?

Pentru a explica exact ceea ce se întâmplă aici, să adăugăm un lucru mult mai mare margin-top la h1.

.card {
  background: #000;
  color: white;
  width: 560px;
  margin: 0 auto;
}

h1 {
  font-size: 24px;
  margin-top: 100px;
}

p {
  font-size: 18px;
  margin-bottom: 100px;
}

.links {
  margin-top: 10px;
}

Văd că oamenii fac asta tot timpul, încercând să împingă titlul în jos în părintele său. Cu toate acestea, mai degrabă decât să lucrăm așa cum era de așteptat, avem un spațiu uriaș deasupra întregii cărți!

  h1 cu marja prăbușită

Acest lucru se datorează faptului că margin-top pe <h1> fuzionează cu margin-top pe elementul părinte.

Nu există nimic care să separe vârful copilului și părintele în acest caz. Deci, când adăugăm margin-top copilului, acesta îl atinge pe cel al părintelui margin-top. Și, așa cum am văzut mai sus, când două margini se ating, ele se îmbină într-o singură marjă.

Deci, în timp ce acordăm marja copilului, aceasta este aplicată părintelui.

Acesta este motivul pentru care oamenii urăsc CSS.

În mod similar, în codul de mai sus am dat toate paragrafele a margin-bottom. Această marjă de pe p.link elementele atinge margin-bottom din .card element, ceea ce înseamnă că cele două fuzionează împreună și marginea afectează .card element în locul linkurilor.

Element de card cu marjă de colaps

Deși acest lucru nu cauzează o problemă pentru site-ul pe care îl creăm în prezent, ar putea cauza probleme dacă ulterior am decide să adăugăm elemente suplimentare pe pagină.

Problema este că o folosim margin cu un scop greșit

Dacă vreau spațiu între partea de sus a .card element și copiii din interiorul ei, nu ar trebui să folosesc margin oricum.

Începătorii se amestecă deseori margin și padding. Regula mea generală este că, dacă doriți spațiu gol, utilizați margin. Dacă doriți mai mult fundal, utilizați padding.

În acest caz, ne dorim .card pentru a avea mai mult fundal, deci nu ar trebui să adăugăm un margin copiilor săi. În schimb, ar trebui să adăugăm padding la acel element în sine.

Rezultatul adăugării căptușelii la elementul părinte

În imaginea de mai sus, putem vedea umplutura și marginea. <h1> deasupra are încă o marjă, dar nu se mai îmbină cu .card deoarece padding a adăugat într-un buffer. Acest lucru împiedică .cardși h1 marja de a se atinge unul pe altul.

Deoarece umplutura adaugă suficient spațiu între <p>s și <h1>s, acum putem elimina marginile pe care le-am adăugat anterior.

Site cu margine-fund mai mare pe ultimul element copil.

Marginile nu se prăbușesc întotdeauna

Există câteva excepții de la marginile de colaps. Descendenții direcți ai părinților grid și flex nu au marje de colaps.

Indică?.

Dar există un pic de o soluție pentru acest lucru, de asemenea, care ne aduce cerc complet înapoi la acele foi de stil agent de utilizator despre care am vorbit la început.

Există o modalitate ușoară de a evita chiar să vă gândiți la prăbușirea marjelor

În primul rând, există regula mea generală despre care am vorbit mai sus:

  • Dacă aveți nevoie de spațiu gol, utilizați margin
  • Dacă aveți nevoie de mai mult fundal, utilizați padding

Asta te va scoate din necazuri de cele mai multe ori. Dar să adăugăm o regulă suplimentară la aceasta care va ajuta și mai mult:

  • Încearcă să eviți margin-top cu excepția cazului în care tu într-adevăr nevoie de el

Această regulă intră într-un pic de conflict cu stilurile user-agent, care stabilesc un margin-top și margin-bottom la o grămadă de elemente, care este unul dintre motivele pentru care deseori voi face așa ceva:

h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol {
 margin: 0 0 1em 0;   
}

Elimină o mulțime de probleme care provin de la prăbușirea marjelor pe cont propriu, precum și diferențele în aspectul dvs. atunci când unele locuri utilizează flex sau grid, iar altele nu.

(Notă: dacă inspectați codul aici pe Routech, veți vedea că și ei fac ceva similar!)

Nu este o soluție perfectă și adesea folosesc puțin margin-top pe anumite subtitrări sau în situații specifice în care este solicitat. Dar o fac foarte intenționat, în loc să las stilurile utilizator-agent să se împiedice într-un mod neprevăzut.

Aceste lecții sunt doar un fragment din cursul meu mult mai amplu de design web receptiv. Pentru a continua această călătorie de codificare, aruncați o privire la curs.

În curs, abordez o introducere în designul web receptiv și mă scufund atât în ​​flexbox, cât și în grilă, încercând în același timp să le arăt oamenilor cât de distractiv este într-adevăr CSS odată ce începeți să înțelegeți cum funcționează.

Codificare fericita 🙂