Revisiting Margin Collapse

Margin collapse is something that mentioned in every CSS book’s first or second chapter. When I learned about the stylesheets in a long time ago, of course, I read about it. These memories a little bit wore out so its time to refresh my knowledge, let’s start it!

Margin collapsing is that when two or more margin value – vertically, top or bottom – adjoining into one. These margins have to relate – or connect – to each other in some way.

Mainly this was needed because of the paragraphs and the others typography related elements. If you use both the top and bottom margin you don’t have to think about the exact values – the sum of both – because if two margins meet the bigger will win.

The usefulness of this is self-evident. If you want to set a margin to 30px, you don’t want the next element also add its own 30px to it. Thus it will collapse and will be 30px the spacing between these because each has a 30px margin alone.

The margin collapsing works with margin-top and margin-bottom values only.

Multiple Margins

So far to this point, it is bright like the sky; understanding the margin collapsing start to be more complicated when we arrive at the parent-children relation (and the exceptions in the next block).

Beforehand I mentioned the multiple – more than two in this case – values. The collapsing also works when you have an extra wrapper element inside it with a component which also has margin.

Having a parent div can cause some unexpected result because your inside element – with margin – overflow outside of it’s parent boundaries. Apparently, the first and the last child element will be problematic.

I use pixel-based values in the examples, but in a production project it is better to use relative units for margins.

In our demo case we have two paragraph – the second in the div – and one div element. The .second-paragraph has a 20px margin-bottom, the .third-paragraph has a 60px margin-top and the div has zerothe zero margin also playsmargin-top value and the 60px value will win and specify this part’s margin value. The math is simple, the bigger beats, the smaller.

In the CodePen example, I tried to illustrate the margins: the top is colored with pink, the bottom is painted with green when they collapse you see a bluish-gray color (because its overflow each other). The div section has a light yellow background. For first view, it can be a little chaotic but if you check the code, you will see the essence.

See the Pen Margin Collapse Demo – Generic by Adam Laki (@adamlaki) on CodePen.

Margins Don’t Collapse When

There are cases where we want to control or disable the margin collapsing; mostly this is actual when you have a parent-children relation:

  • In case of margin-top if there has any padding, border, inline part, block formatting context or clearance between the parent element’s margin and the first-child element’s margin.
  • In case of margin-bottom if there has any padding, border, inline element, or height (height, min-height, max-height) between the parent and the last-child element.
  • Using display: flex; declaration on the container the children element’s margin doesn’t collapse too.
  • Declaring overflow: auto; (works with every value except visible) on the parent prevents collapsing too.
  • Display elements with table-cell or table-row value will not collapse because these elements don’t have a margin.

See the Pen Margin Collapse Demo – Disable Collapsing by Adam Laki (@adamlaki) on CodePen.

In case of empty element, the collapse won’t work if it has padding, border, inline content, height or min-height which separate the items.

In case adjacent siblings the collapsing not working when the latter element clear a float.

Using Negative Margins

We can also have collapse margins with negative values. If you have a positive (100px) and a negative (-50px) value than the margin will be the positive – negative: 100px + (-50px) = 50px.

See the Pen Margin Collapse Demo – Negative Margin by Adam Laki (@adamlaki) on CodePen.

If you have two negative values than the more significant negative (not that which is closer to zero) will win like -100px and -50px will be -100px.

Useful Link(s)