Kuinka ymmärtää CSS-marginaaleja ja työskennellä niiden kanssa

CSS saa huonon rapin, koska se ei käyttäydy ihmisten tavoin. Yksi asioista, joka heittää ihmiset eniten pois, ovat marginaalit. Ne näyttävät niin yksinkertaisilta, mutta niillä on potentiaalia aiheuttaa todella outoja asioita.

CSS: ään juuri aloittaville ihmisille se on helposti yksi niistä asioista, joka saa sinut ajattelemaan "tämä on tyhmä kieli, jolla ei ole mitään järkeä!"

Näen sen päivittäin - sekä luokkahuoneessa, kun ihmiset yrittävät selvittää välilyöntejä, että myös YouTube-kommenttini-osioissani.

Tavallaan marginaalit ovat yleensä pieni mikrokosmos CSS: ää. CSS näyttää pariltaan niin yksinkertaiselta property: value, mutta edetessäsi huomaat, että siellä on paljon tekemistä.

Marginaalit näyttävät myös niin yksinkertaisilta. Lisää marginaali ja lisää tyhjää tilaa kyseisen elementin ympärille. Mutta sitten yhtäkkiä he käyttäytyvät hieman eri tavalla yhdessä tilanteessa tai lisäät joitain margin-toplapsielementtiin, ja sen sijaan vanhempi liikkuu alaspäin.

Seurauksena on turhautuminen.

Toivon tässä artikkelissa valottavanni hieman marginaalien toimintaa. Tarkastelemme joitain yleisiä ongelmia ja yksinkertaisia ​​ratkaisuja näihin ongelmiin.

Kaiken tämän selvittämiseksi käytän esimerkkejä reagoivasta Web Design Bootcampista Scrimballa, josta otin tämän yksinkertaisen asettelun:

CSS-asettelu marginaaleilla ja täytteillä

Mitä marginaalit ovat?

Ennen kuin hyppäämme todella syvälle alueelle, haluan varmistaa, että tiedämme kaikki marginaalit!

Oletan, että me kaikki tiedämme, että marginaalit ovat osa laatikkomallia, marginaali on kokonaan ulkopuolelta, joka seuraa itse sisältöä, pehmustetta ja reunaa.

MDN selittää ne todella hyvin (painopiste minun):

Reuna on uloin kerros, joka ympäröi sisällön, pehmusteen ja reunuksen välinä tämän ruudun ja muiden elementtien väliin . Sen kokoa voidaan hallita marginaalilla ja siihen liittyvillä ominaisuuksilla.

Toisin sanoen, se on käytännössä tyhjä tila, jota voimme käyttää luomaan tilaa laatikon toiselle ruudulle.

Käyttäjäagentin tyylitaulukoiden käsittely

Selaimissa on oletusarvoisesti yllättävä määrä CSS: ää, jota kutsumme käyttäjäagenttityylitaulukoiksi . Nämä tyylit ovat syy siihen, että ilman CSS: ää meidän puolestamme

on suurempi kuin

ja miksi siinä on marginaali, jonka pyrimme aina poistamaan.

Nämä tyylit ovat tärkeitä, mutta ne johtavat myös yhteen suurimmista ongelmista, joihin ihmiset törmäävät marginaaleilla! Marginaalit eivät ole oletusarvoisesti 0kaikille elementeillemme, ja tämä voi aiheuttaa kaikenlaisia ​​outoja asioita, joita tutkimme pian.

Luetteloissa, lauseissa, kappaleissa ja otsikoissa on kaikki margin(muun muassa). Vaikka joskus ne ovat vain vähäisiä haittoja, kappaleiden ja otsikoiden oletusmarginaali näyttää olevan se, joka aiheuttaa useimmat ongelmat alusta.

Oletusarvoisesti tekstielementin vasen ja oikea marginaali on asetettu 0, mutta niissä kaikissa on margin-topja margin-bottom.

Sanon usein ihmisille, että nämä ylä- ja ala-oletukset ovat suunnilleen samat kuin font-sizekyseisen elementin, koska se on totta

yhtä hyvin kuin

kautta

. Sillä

se on oikeastaan 0.67emja varten

se on 0.83em.

Tämä tarkoittaa, että sivumme elementtien välillä on tilaa, vaikka emme ole nimenomaisesti asettaneet marginaalia.

Palaamme näihin oletusarvoihin hetkessä.

Romahtavat marginaalit

Päänsäryt alkavat usein romahtavat marginaalit.

Kun kahdella elementillä on pystysuora marginaali, joka koskettaa toisiaan, ne sulautuvat tosiasiallisesti.

Se on jo outoa käyttäytymistä, ja lisää se sitten siihen, että se on tarkoitettu vain pystysuorille marginaaleille (ylhäältä ja alhaalta), ymmärrän, miksi ihmiset sekoittuvat ja ärsyttävät niitä.

Voimme nähdä tämän toiminnassa seuraavan esimerkin avulla:

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

.linksLuokan viimeinen kappale on selventää, mitä täällä tapahtuu.

When people do something like this, they expect the margin between the middle paragraph and the links below it to be 80px (40px + 40px), but in reality, it's 40px. The two margins are touching each other, so they merge into one another.

Paragraph and links with 40px space between

To push it even more, let's give our

s' a  margin-bottom to 100px:

p { font-size: 18px; margin-bottom: 100px; } .links { margin-top: 40px; } 

Again, the two margins don't add together, they collapse into one another, so the total space here is 100px.

Paragraph and links with 100px space between

This is a good thing

In cases like this, it's actually a good thing, though. If there are several elements with different margins, there is no need to add the margins together to see how large the gap between the elements is because we can rely on the fact that the larger margin always wins.

We often don't even think about it, it just works the way we expect it to work.

When it's not a good thing

That said, one instance where margin collapse causes all sorts of confusion is when the first child within an element has a margin-top that merges with the parent's margin-top.

Let's look at that same screenshot again:

Paragraph and links with 100px space between

There is a white space between the top of the viewport and the black box. That's not from the body (it's much bigger than the 8px margin the body would have).

Care to guess where it's coming from?

It's actually coming from the

at the top of that black box.

Remember when I mentioned that the user-agent stylehsheets can do some odd things?

To help explain exactly what's happening here, let's add a much bigger margin-top to the 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; } 

I see people do this all the time, trying to push the title down within its parent. However, rather than working as expected, we get a giant space on top of the entire card!

 h1 with collapsed margin

This is because the margin-top on the

merges with the margin-top on the parent element.

There is nothing separating the top of the child and the parent in this case. So when we add margin-top to the child, it touches the parent's margin-top. And, as we saw above, when two margins touch one another, they merge into a single margin.

So while we are giving the margin to the child, it's being applied to the parent.

This is why people hate CSS.

Similarly, in the code above we gave all paragraphs a margin-bottom. That margin on the p.link elements touches the margin-bottom of the .card element, which means that the two merge together and the margin affects the .card element instead of the links.

Card element with collapse margin

Although this isn't causing an issue for the site we are currently creating, it could cause problems if we later decided to add further elements to the page.

The problem is, we're using margin for the wrong purpose

If I want space between the top of the .card element and the children inside it, I shouldn't be using margin anyway.

Beginners often get mixed up between margin and padding. My general rule of thumb is if you want empty space, use margin. If you want more background, use padding.

In this case, we want our .card to have more background, so we shouldn't be adding a margin to its children. Instead we should add padding to that element itself.

Result of adding padding to the parent element

In the image above, we can see the padding and the margin. The

on top still has a margin, but it's no longer merging with the .card because the padding has added in a buffer. This prevents the .card's and h1 margin from touching one another.

As the padding adds sufficient space between the

s and the

s, we can now remove the margins we previously added to them.

Site with larger margin-bottom on last child element.

Margins don't always collapse

There are some exceptions to collapsing margins. The direct descendants of grid and flex parents do not have collapsing margins.

Cue the ?.

But there is a bit of a workaround for this as well, which brings us full circle back to those user agent-stylesheets we talked about at the start.

There is an easy way to avoid even thinking about collapsing margins

First off, there is my general rule of thumb that I talked about above:

  • If you need empty space, use margin
  • If you need more background, use padding

That will get you out of trouble most of the time. But let's add an extra rule to this that will help even more:

  • Try to avoid margin-top except when you really need it

This rule is in a bit of conflict with the user-agent-styles, which set a margin-top and margin-bottom to a bunch of elements, which is one reason I often will do something like this:

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

It eliminates a lot of the issues that come from collapsing margins on their own, as well as differences in your layout when some places are using flex or grid and others are not.

(Note: if you inspect the code here on freeCodeCamp, you'll see they do something similar as well!)

It's not a perfect solution, and I often do use a little margin-top on certain subtitles or in specific situations where it's called for. But I'm doing it very intentionally instead of letting the user-agent-styles potentially get in the way in some unforeseen way.

These lessons are just a snippet of my much larger course on responsive web design. To continue this coding journey, take a look at the course.

In the course I cover an introduction to responsive web design, and dive into both flexbox and grid, all the while trying to show people how much fun CSS really is once you start to understand how it works.

Happy coding :)