CSS Fundamentals

Collapsing Margin

CSS Fundamentals

Lesson Description

The "Collapsing Margin" Lesson is part of the full, CSS Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Kevin explains collapsing margins in CSS, demonstrating how touching margins merge and cause unexpected spacing, and shows strategies like using padding to prevent it, while also mentioning future CSS solutions like margin trim.

Preview

Transcript from the "Collapsing Margin" Lesson

[00:00:00]
>> Kevin Powell: I mentioned one weird thing that we have in CSS is we have collapsing margins, and that's a weird term. I actually prefer thinking of it as merging maybe, just we have margins that can move into one another. So to understand what I mean by that is I have an element here, a demo box, very simple, and it has three children inside of it. And those three children are just three paragraphs that have padding, or sorry, not padding, but margin on the top and the bottom.

[00:00:28]
They have 20 pixels on the top and the bottom. What's interesting here is if I make the, actually we're going to leave that one alone, we're going to make the bottom 200, there we go, and it adds the space that you'd expect there, but it might not be as much as you think. Because if we, or actually, I'm going to leave that. That's fine, we get a bunch of space. Now if I make the margin top 200, you'd expect the space to get a lot more, but the space actually stays the same.

[00:00:56]
And that's because the margins are collapsing into one another. And that's a really weird concept. This is one of those things I definitely see when people are like, oh, CSS isn't intuitive, collapsing margins, it's not intuitive, but once you know what's happening, at least you can understand why this is what's happening. So in my dev tools, I can see the margin on here is going from the bottom of this all the way down to the next one in that orange space.

[00:01:22]
And if I highlight the other one, the same thing is happening on the top. Where the margins are literally taking the exact same place. I don't like using the word literally usually, but it is literally in this case, they're using up the same amount of space. So anytime the margins of two elements touch one another, those margins will collapse into one another, or merge into one another, however you want to think about it.

[00:01:51]
They occupy the same space. In this setting, it's actually okay. All elements have a margin top and bottom, like our paragraphs or headings, all of the text related things, they always have that margin on them. And so because they have a top and bottom, it prevents double spacing, sure, it doesn't really get in the way too much. And it's not that complicated, there's workarounds you can get there.

[00:02:14]
Where it does get a little bit weird is, let's add the margin top here of 2000 pixels. And if we go all the way down, the parent is what's getting pushed all the way down. So that margin on this paragraph on the top is actually collapsing with its parent margin on the top and pushing everything down. It's for the exact same reason. There's no space between these two. The first element is touching the top of its parent.

[00:02:46]
That means their margins are touching one another, so their margins collapse into one another and we push the parent down with the child. Definitely a strange behavior. I'd be nice to say, you know, that this is super intuitive, it's a really strange thing, but it's how it works. There's nothing we can do about it. In terms of that is what the behavior actually is, and it's one of those things that can sometimes get people a little bit frustrated.

[00:03:13]
Usually though, if you're adding margin top to the first element in something, it's because you want to push that element down. But if I want to push the first element down inside of a parent, there's an alternative approach that I could take. Anyone here want to venture a guess? Push down the parent without moving the parent. I want to move the first element down, keeping the parent in the same place.

[00:03:36]
I heard someone say it. Padding, yeah, thank you, Grant. We want to, you want more background, you're pushing an element down inside of the parent, so instead of adding a margin to the top, let's just remove all of those margin tops, I could just add a padding to the top. I'm not using logical properties. I apologize for this one. I could say 200 pixels, and then I can actually move the element down within the parent.

[00:04:03]
This is generally the easiest way to work, is to on elements, avoid having margins top and bottom, and try and keep margins only between siblings. It's sort of the way we can manage them. There's other ways, this is where gap comes in, we're going to be seeing gap very soon, there is a bit of a lifesaver on this. But there's a few different strategies that we can use to help us with this. There's a very common strategy, well, first I mentioned, more background equals padding.

[00:04:29]
That's the first line of thought that I always want you to have. The other one is that we want to, or people often remove unwanted margins, and one way we can do that is this. It's another time the universal selector comes in, a margin of zero on everything, and then you reintroduce margins in different places where you need to have them. It's a very common approach, and again, margin is layout related, it's not going to be inherited, so if we want everything to have a margin of zero, we do need to use the star selector.

[00:04:58]
Another option is to get a little bit more specific, where we haven't seen this before, but we have seen the combinator before. So we can say an element with padding, and we can select every child of it and give that a margin block, so margin top and bottom of zero, and then again we reintroduce the padding, or not the padding, but the margin where we need to have it on specific elements within there.

[00:05:23]
There's lots of different ways and best practices and preferences and all of that that go into these types of things. What I'm going to recommend is over here is something like this a lot of the time. It's not necessarily on larger scale projects, there might be approaches that work better with this type of approach, but for something simple like we're working on, something like this can actually work really well.

[00:05:48]
And for this, what we're doing is using a new pseudo-class. We've seen pseudo-classes before. These ones are very specific. I can just say my first child that's a direct sibling of whatever element it is that I want, I can say the margin on the block start is zero or a margin top is zero, and then the last child gets a margin of zero at the bottom. And that just cuts off those margins. There could be use cases you run into where this isn't exactly what you want, so you do want to be a little bit careful with it, but a lot of the time this is the desired behavior, so it is definitely an approach you could use, just don't call it element with padding.

[00:06:26]
Do it on the class that you have. So in our example, our hero, this would be a good use case for it. Yeah. I've heard that it's best to choose one or the other if you're going to use margin top versus margin bottom, so you don't come across this weirdness. Do you, have you, in your experience, determined which one is actually better, top or bottom? I would go with, most people, it's like intuitive to go with a margin bottom.

[00:06:56]
It just feels more natural to have a margin bottom. I prefer margin top. The reason for it is it gets into a bit more of an alternative method that you can use that I was going to mention. I do use it in my other course with Frontend Masters, which was this one. It's a bit more of an advanced use case, so I didn't want to get into it in this one, but it's where you say the margins are zero everywhere or you could do it like this, but you're generally saying zero and then you have another class that's reintroducing a margin top to all the elements.

[00:07:30]
And it's just from a typography perspective, like you can even see here in this layout, the heading is closer to this text than the text above it. So if I have, if I set my margins, margin top in ems, it will match the font size of the element, like a 1em margin top. So if I have a bigger piece of text, the margin on the top of it will always be bigger, so it creates a bit more of a separation with a heading going into like the next section of content.

[00:07:59]
It's definitely the way I would tend to lean toward, but for a lot of simpler things, I do think this just eliminate in the specific places that you don't want them and everything would be fine. There is a fix coming as well. There's a new CSS property on the way called margin trim. As we're recording this, it's only supported in Safari, so we can't really use it in production yet. I'm really looking forward because you literally just say, if the element's the first thing, like the top and bottom margins, it'll also work on the other axis.

[00:08:27]
So if you had a margin on the left or right, you could trim. If the margin is touching the edge of the parent, it just will trim it off, essentially. So looking forward to that gaining support, but until it does, we do need to have an alternative.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now