loading...

CSS Margin Collapse

ziizium profile image Habdul Hazeez Updated on ・6 min read

FrontEnd Development Zero to Hero (67 Part Series)

1) FrontEnd Development: Zero to Hero 2) What is the Internet 3 ... 65 3) What is the Web 4) Web Browsers 5) Tools for Web Development 6) Introduction to HTML 7) History of HTML 8) The HTML specification 9) HTML Elements and Tags 10) Replaced Element and Void Element 11) Writing Accessible HTML 12) Validating HTML documents 13) HTML Resources and Reference 14) Introduction to CSS 15) History of CSS 16) The CSS Specification 17) CSS Properties 18) CSS Selectors 19) CSS Units 20) CSS Specificity 21) The CSS Cascade 22) CSS Inheritance 23) The CSS Box model 24) CSS Margin Collapse 25) CSS Positioning 26) CSS z-index 27) CSS colors 28) CSS Backgrounds 29) CSS Variables 30) CSS Floats 31) CSS Block Formatting Context 32) CSS Flexbox part 1 33) CSS Flexbox part 2 34) CSS Grid part 1 35) CSS Grid part 2 36) CSS Media Queries 37) CSS Typography 38) CSS Animations and Transitions 39) CSS Naming conventions 40) Writing maintainable CSS 41) CSS References and Resource 42) Introduction to JavaScript 43) History of JavaScript 44) The EcmaScript specification 45) Introduction to programming 46) JavaScript Variables 47) JavaScript Arrays 48) JavaScript Objects 49) JavaScript Numbers 50) JavaScript Conditionals 51) JavaScript Loops 52) JavaScript Functions 53) The Document Object Model 54) Introduction to Ajax 55) JavaScript References and Resource 56) Introduction to Web Design 57) History of web design 58) Site Layouts in CSS 59) Introduction to Responsive web design 60) Introduction to Progressive Enhancement 61) Introduction to User Interface design 62) Introduction to user experience design 63) Introduction to Web accessibility and usability 64) Introduction to Color theory 65) Web design References and resource 66) Series final project 67) Building your career as a developer

Margin collapse is one of the tricky things about margins in CSS and it's a foundational concept in understanding the CSS Box model. Not knowing when a margin collapse, can be a point of frustration and when they do you just have to deal with it. This post will attempt to introduce and treat this concept in a beginner-friendly approach with code snippets and images from the browser Developer Tools.

From the previous post, we learned that the margin property applies to block level element and it's a shorthand for four other properties:

  • margin-top
  • margin-right
  • margin-bottom
  • margin-left

Now, when the margin-top and margin-bottom of this element combine into a single margin whose size is the largest of the individual margins (or just one of them, if they are equal). This behavior is known as margin collapsing and it usually occurs in three cases:

  • Adjacent siblings
  • No content separating parent and descendants
  • Empty blocks

ADJACENT SIBLINGS

From the Mozilla Developer Network (emphasis mine):

The margins of adjacent siblings are collapsed (except when the latter sibling needs to be cleared past floats).

This translates to: If you have one or more block-level elements appearing one after the other from the top of the page i.e vertically, their margin will collapse.

Let's explain with code.

Don't forget to create your HTML and CSS files to follow along, and remember all HTML snippets will be in the body tag.

Given the code snippet below:

<div class="parent">
  <div class="child"></div>
  <div class="child two"></div>
</div>
/* cosmetics*/
.parent {
  margin-top: 32px;
  margin-right: auto;
  margin-left: auto;
  margin-bottom: 32px;
  background-color: rgb(200,200,200);
  width: 500px;
}

/*
 * The real deal is the margin-bottom value, the rest
 * are cosmetics.
*/
.child {
  margin-top: 30px;
  margin-right: 20px;
  margin-bottom: 50px;
  margin-left: 20px;
  width: 100px;
  height: 100px;
  background-color: #1560bd;
}

.child.two {
  margin-top: 20px;
  background-color: red;
}

From the snippet above, the margin-bottom of the child element is 50px and we gave the adjacent box a margin-top of 20px. Normal intuition will tell you that these values should add up since they are block-level element's and the space between .child and .child.two should be 70px, but that's not the case.

Save your files and load the HTML in your browser, Use "Inspect Element" on the blue box, Navigate to the Layout tab and click on the Box Model, you will realize that the space between the blue box and the red box is still 50px even though the red box has a margin-top value of 20px, the browser did not take this value into consideration. When something like this happens, the margin is said to have collapsed.

Margin Collapse in CSS

But what happens if we have one negative margin value? This will cause a slight deviation in the behavior of margin collapsing and the positive and negative margins will be added together to reach the final margin.

This means if our blue box has a margin-bottom of 50px and the red box has a margin-top of -20px, the browser will calculate the margin between them as:

  • 50 + (-20) => 50 - 20 => 30

The value gotten from the above calculation will be the space between the boxes.

Change the margin-top of the .child.two CSS rule (the red box) to a negative value:

.child.two {
  margin-top: -20px; /* Add this */
  background-color: red;
}

Save your CSS file, and refresh your browser. The red box will now move up a little bit and will occupy part of the bottom margin of the blue box.

Margin Collapse in CSS

NO CONTENT SEPARATING PARENT AND DESCENDANT

The title says it all, but Mozilla Developer Network has more:

If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of one or more of its descendant blocks; or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block from the margin-bottom of one or more of its descendant blocks, then those margins collapse. The collapsed margin ends up outside the parent.

Update your CSS and HTML with the code below:

<h1>This is the header</h1>
<div class="parent">
  <p class="child">Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
.parent {
  margin-top: 50px;
  margin-right: 0;
  margin-bottom: 25px;
  margin-left: 0;
  outline: 5px solid red;
}

.child {
  margin-top: 20px;
  margin-right: 0;
  margin-bottom: 0;
  margin-left: 0;
  background: #1560bd;
  color: #ffffff;
}

Save your files and refresh your browser, you will notice that the browser did not render the margin-top property of the child element because the .parent has a higher margin-top value of 50px, but the browser knows the margin-top value of the child. How? Perform the following steps:

  • Use "Inspect element" on the paragraph
  • Navigate to the Layout tab
  • Click on the Box Model

You will notice that the browser actually recognized the 20px.

Margin Collapse in CSS

And if you hover your mouse (or pointing device) over the margin value in the box model, the browser will highlight (in yellow) where the margin should have occupied in the web page, but, the margin is not rendered because it collapsed with the parent margin.

Margin Collapse in CSS

EMPTY BLOCKS

Empty blocks are block level element with no content. And If there is no border, padding, inline content, height, or min-height to separate these block's margin-top from its margin-bottom, then its top and bottom margins collapse.

Update your CSS and HTML to match the following snippet.

<div class="box"></div>
.box {
  background: red;
  width: 120px;
  margin-top: 20px;
  margin-bottom: 50px;
}

Save your files and refresh your browser. Use the Developer Tools to view the Box Model, hover your mouse over the yellow area of the Box Model you will notice that the margin bottom is not rendered but the browser acknowledge its value in the box model (highlighted in the image).

Margin Collapse in CSS

However, if you give the empty block a height or min-height, it will not collapse.

.box {
  background: red;
  width: 120px;
  margin-top: 20px;
  height: 120px; /* Add this */
  margin-bottom: 50px;
}

Margin Collapse in CSS

The question now is How can we stop margins from collapsing?

PREVENTING MARGIN COLLAPSE

From previous explanation we can realize that only consecutive elements can collapse into each other. Putting an element with a non-zero height between our elements forces them to display their margins. This element can be a border or a padding.

Let's demonstrate.

Refer to the code snippet under NO CONTENT SEPARATING PARENT AND DESCENDANT, add a border declaration to the CSS .parent rule:

.parent {
  margin-top: 50px;
  margin-right: 0;
  margin-bottom: 25px;
  margin-left: 0;
  outline: 5px solid red;
  border-top: 1px solid #000; /*Add this*/
}

Save your file and refresh your browser. The margin will now take effect.

Preventing Margin Collapse

Now delete the border declaration you just added to the .parent CSS rule, and add the following to your HTML just before the paragraph with the .child class:

<div style='padding-top: 1px'></div>

Save your file and refresh your browser, if you've done everything right you will get the same result similar to when you applied a border with CSS.

Another way to avoid margin collapsing is to consider applying only top margin or bottom margin to elements

Note that the margins of floating and absolutely positioned elements never collapse.

Speaking of Positioning. That's Next.

FrontEnd Development Zero to Hero (67 Part Series)

1) FrontEnd Development: Zero to Hero 2) What is the Internet 3 ... 65 3) What is the Web 4) Web Browsers 5) Tools for Web Development 6) Introduction to HTML 7) History of HTML 8) The HTML specification 9) HTML Elements and Tags 10) Replaced Element and Void Element 11) Writing Accessible HTML 12) Validating HTML documents 13) HTML Resources and Reference 14) Introduction to CSS 15) History of CSS 16) The CSS Specification 17) CSS Properties 18) CSS Selectors 19) CSS Units 20) CSS Specificity 21) The CSS Cascade 22) CSS Inheritance 23) The CSS Box model 24) CSS Margin Collapse 25) CSS Positioning 26) CSS z-index 27) CSS colors 28) CSS Backgrounds 29) CSS Variables 30) CSS Floats 31) CSS Block Formatting Context 32) CSS Flexbox part 1 33) CSS Flexbox part 2 34) CSS Grid part 1 35) CSS Grid part 2 36) CSS Media Queries 37) CSS Typography 38) CSS Animations and Transitions 39) CSS Naming conventions 40) Writing maintainable CSS 41) CSS References and Resource 42) Introduction to JavaScript 43) History of JavaScript 44) The EcmaScript specification 45) Introduction to programming 46) JavaScript Variables 47) JavaScript Arrays 48) JavaScript Objects 49) JavaScript Numbers 50) JavaScript Conditionals 51) JavaScript Loops 52) JavaScript Functions 53) The Document Object Model 54) Introduction to Ajax 55) JavaScript References and Resource 56) Introduction to Web Design 57) History of web design 58) Site Layouts in CSS 59) Introduction to Responsive web design 60) Introduction to Progressive Enhancement 61) Introduction to User Interface design 62) Introduction to user experience design 63) Introduction to Web accessibility and usability 64) Introduction to Color theory 65) Web design References and resource 66) Series final project 67) Building your career as a developer

Posted on by:

ziizium profile

Habdul Hazeez

@ziizium

I teach and write code with interests in Web Development, Computer Security, and Artificial Intelligence.

Discussion

markdown guide