I have look for a while now on this problem and have not found a straight answer. When adding a margin top to an element, in my case it happens mostly with headings. In many occasions the margin-top is shared with the parent.
HTML
<div>
<h1>My title</h1>
</div>
CSS
div{
padding:20px;
}
h1{
margin-top: 20px;
}
The result of the previous code will also add a margin-top to the div, as if we had the following:
div{
padding:20px;
margin-top:20px; /*this one is implemented by the browser, not written on the code*/
}
A way to solve this is by adding overflow:auto
to the parent, in this case the div css has:
div{
padding:20px;
overflow:auto;
}
Although the previous example solves the problem, it is not clear to me WHY???. This has something to do with "collapsing margins", where apparently a margin is combined with the parent's margin. But why????
How do we know when a parent will collapse the margin of the child and when not, what is the purpose of this property of the blocks, or is it a bug?
Here's a JSFiddle demo of the problem.
And Here is a JSFiddle demo of the solution
Thanks.
Inheriting Margins The inherit value transfers the margins of a parent to a child element. The example below shows that the parent element <div> has a specific value of the left margin, and the child element <p> has the inherit value of the left margin.
The margin-top CSS property sets the margin area on the top of an element. A positive value places it farther from its neighbors, while a negative value places it closer.
"Margin is that space between the edge of an element's box and the edge of the complete box, such as the margin of a letter. 'top' displaces the element's margin edge from the containing blocks box, such as that same piece of paper inside a cardboard box, but it is not up against the edge of the container."
Adjusting the Margin Size of an HTML Element With CSS You can remove this margin by setting the top and left margin to zero. Like the padding and border, the sizes of specific sides of the margin can be set using margin-left , margin-right , margin-top , and margin-bottom .
Thank you all for your answers, @gaurav5430 posted a link with a very precise definition that I would like to summarize into this answer. As of why they decided that this elements should behave like this it is still unclear for me; but at least we were able to find a rule that applies to collapsing margins:
"In simple terms, this definition indicates that when the vertical margins of two elements are touching, only the margin of the element with the largest margin value will be honored, while the margin of the element with the smaller margin value will be collapsed to zero
Basically in our example on the original question, the biggest margin-top is the one of the <h1>
therefore taken and applied to the parent <div>
.
This rule is cancelled for:
That is the reason why overflow:hidden
solved the issue.
Thanks @gaurav5430; here is the reference: http://reference.sitepoint.com/css/collapsingmargins
Also thanks to @Adrift that posted very good resources, although I found @gaurav5430's answer more straight forward and easier to understand.
If element is the first child, it will add the margin-top to the parent element, collapsing with the margin-top of parent element.
The why sometimes margin does not collapse is clearly said in W3 collapsing-margins section.
I recommend using padding-top or this workaround: Margin on child element moves parent element, since overflow: hidden
can add collateral damage.
see this example: fiddle
HTML:
<div id="outside">
<div id="div1">
<h1>margin in parent</h1>
</div>
<div id="div2">
<h1>margin inside</h1>
</div>
</div>
CSS:
#outside {
background-color: #ccc;
border:1px solid #000;
}
#div1 {
background-color: #66d;
}
#div1 h1 {
margin: 20px 0 0 0;
}
#div2 {
background-color: #6d6;
}
#div2 h1 {
margin: 20px 0 0 0;
}
here is a nice article, with a slight explanation
http://reference.sitepoint.com/css/collapsingmargins
find this on the above link...
Collapsing Margins Between Parent and Child Elements
So far, we’ve only addressed the collapsing effect on adjacent elements, but the same process holds true for parents and children whose margins touch. By “touch,” we mean the places at which no padding, borders, or content exist between the adjacent margins. In the following example, a parent element has a child element on which a top margin is set:
h1 { margin: 0; background: #cff; } div { margin: 40px 0 25px 0; background: #cfc; } p { margin: 20px 0 0 0; background: #cf9; } In the style sheet above, you can see that a top margin value is declared for the p element, and in the code excerpt below, you can see that the p element is a child of the div element:
Heading Content
Paragraph content
The result of this code is illustrated in Figure 2.Figure 2. Collapsing margins on a child paragraphAn illustration of collapsing margins between a h1 element and a div element with a child p element. There's a 40 pixel vertical gap between the h1 element and the paragraph content. You may have expected that the paragraph would be located 60px from the heading, since the div element has a margin-top of 40px and there is a further 20px margin-top on the p element. You may also have expected that 20px of the background color of the div element would show above the paragraph. This does not happen because, as you can see in Figure 2, the margins collapse together to form one margin. Only the largest margin applies (as in the case of adjoining blocks), as we’ve already seen.
In fact we would get the same result if our div element had no top margin and the p element had a 40px margin-top. The 40px margin-top on the p element effectively becomes the top margin of the div element, and pushes the div down the page by 40px, leaving the p element nesting snugly at the top. No background would be visible on the div element above the paragraph. ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With