Vertical Margins Disappear When Parent Is Set to Overflow:Visible

Vertical margins disappear when parent is set to overflow:visible

It's because of collapsing margins:

If you have overflow: hidden, the margins of the inner div remain inside the outer div.

If you have overflow: visible, the top and bottom margins collpase with the zero margins of the outer div, because they touch each other. This is then recalculated to have the same as the inner margin.

So, overflow: hidden will break collapsing margins with the ones inside. You could break the margin collapsing by giving the outer div a padding or a border. So they won't touch each other and so no collapsing

http://www.howtocreate.co.uk/tutorials/css/margincollapsing

Vertical margins disappear when parent is set to overflow:visible

It's because of collapsing margins:

If you have overflow: hidden, the margins of the inner div remain inside the outer div.

If you have overflow: visible, the top and bottom margins collpase with the zero margins of the outer div, because they touch each other. This is then recalculated to have the same as the inner margin.

So, overflow: hidden will break collapsing margins with the ones inside. You could break the margin collapsing by giving the outer div a padding or a border. So they won't touch each other and so no collapsing

http://www.howtocreate.co.uk/tutorials/css/margincollapsing

Why is this floated div being pulled down by the margin its sibbling?

Give an overflow:hidden to the parent div, ie .content

margin-top does not work properly

Give an overflow:hidden to the parent div, ie #first

This happens because of collapsing margins. Vertical margins disappear when parent is set to overflow:visible

Margin on child element moves parent element

Found an alternative at Child elements with margins within DIVs You can also add:

.parent { overflow: auto; }

or:

.parent { overflow: hidden; }

This prevents the margins to collapse. Border and padding do the same.
Hence, you can also use the following to prevent a top-margin collapse:

.parent {
padding-top: 1px;
margin-top: -1px;
}

2021 update: if you're willing to drop IE11 support you can also use the new CSS construct display: flow-root. See MDN Web Docs for the whole details on block formatting contexts.


Update by popular request:
The whole point of collapsing margins is handling textual content. For example:

h1, h2, p, ul {
margin-top: 1em;
margin-bottom: 1em;
outline: 1px dashed blue;
}

div { outline: 1px solid red; }
<h1>Title!</h1>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
</div>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
<ul>
<li>list item</li>
</ul>
</div>

Can't prevent margins from collapsing

The problem is that the element you want the margin-bottom on are floated. Therefore they don't extend their parent's height. so if you aply the margin on the parent, it will be "under" the floated elements.

Explanation for your case :

In your example li.product has 2 children : a and gk-columns . .gk-columns has only floated children so its height is 0 because floated elements don't extend parent's height. Therefore the height of li.product is only extended by the a tag which is 28px.

So if you aply margin-bottom:50px; on li.product it will push the content only of

28px + 50px = 78px

which is less than the height of the floated div.

You can solve this with several solutions :

solution 1
add the margin-bottom on the floated elements like this for your example :

.gk-columns>div{
margin-bottom:50px;
}

Solution 2
if the height of the children elements is fixed set the height to the parent element so it covers the height of the floated children like this for you example :

.gk-columns{
height:159px;
}

How does the margin collapsing of parent and first/last child work?

I threw together this little demo to help demonstrate the way this works:

http://jsfiddle.net/9pq8bm0o/

As you can see, I've made three elements, all nested within each other. The 2 inner containers both have a top margin value of 20px, and the outermost container has a top border (one of the things that is considered a margin separator).

So what does this mean?

Because there is no separation at the top of the two child elements, there is only 20px of space in between the outermost container and BOTH of the two child elements... the inner-most child has had it's margin collapse. Conversely, that margin that is there exists within the outermost container simply because of that border.. if you remove the border, all three elements will share the same 20px of margin which will be outside of all three containers.

So why is it like this?

The best way to think about margin collapsing is like this:
Asking for a margin on an element will ensure that it has that much margin at it's top, and nothing more (unless it's forced to have more).. So looking at my example, Does the middle .parent element have 20px of space above it? Yes, it does. Does the innermost child .child have 20px of space above it? Yes, it also does... so the margin rule is being applied correctly. It doesn't matter where that space lives, as long as it is there.

Imagine that there was a border around the .parent element, but the margin was still displayed the way it is without, and then ask those same questions.. Does the .parent element have the space? Yes, but does the .child element? No, it no longer would, because there would not be 20px of space in between it and the border that is now sitting above it... So, in reality, the space does not collapse, so that both of those questions can be answered as a "yes".

I hope that helps.. it's a little less of a direct answer to your question, and more of the theory behind how it works, so to put things a bit more plainly:

tl;dr

Margin, unlike padding, is meant to add space outside of elements. Because of this, margin will always collapse to the highest parent element whenever possible, to ensure that space is always "outside". Because it is outside of the element, it can count towards multiple different elements, as they all share that "outside" space.

CSS Right Margin Does Not Work Inside a Div With Overflow Scroll

TL;DR:

Margins are for moving an element in from the wrapper, not expanding the wrapper outwards.

The long explanation:

This behavior is consistent with specifying a width in addition to a horizontal margin anywhere in the document. To break it down, consider the following snippet, where I specificity a wrapper without an overflow property, and the margin does not expand the wrapper element.