Why does putting a margin on one div move its container? - html

I've a container div which has another div inside it. When I apply a margin to the inner div it appears to a margin-top to the container div (although it doesn't give a left margin)
http://belfastswimmingteacher.com/mockup.html
What's the craic?

You can either float the halfLeft div, or add padding-top to #content.
This is known as margin collapsing, and whilst may produce this unwanted behaviour, is in fact intended and correct.

Related

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

MDN says:
If there is no border, padding, inline content, or clearance to separate the margin-top of a block with the margin-top of its first child block, or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block with the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.
I don't understand the last sentence. Why does the collapsed margin end up outside the parent? If it ends up outside the parent, where will it go? I have searched the web and read several tutorials about margin collapsing, but I didn't find anything about this.
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.

Padding/Margin/Border On Element Does Not Change DIV Height

Here is a very simply jsFiddle to demonstrate my problem: http://jsfiddle.net/ryandlf/mSmUv/4/
When an element has a top padding or margin and it sits on the first line within a div, the div does not respect that padding or margin and push the element down. In most cases this isn't an issue, but for example, if I have a button that has a top border and padding the top of the border will be cut off because the div is not taking into consideration the padding value.
Is there a workaround for this other than just blindly setting margins or padding on every container div element and hoping I have added enough to account for any internal element that might be affected?
your link with class button is not a block element, it is inline element. Change this default behaviour by adding dispaly: block to it and it will work as expected. Proof available on jsfiddle.
So to sum up, the problem is not with the div - it is the problem with css - inline elements ignore margin and padding because they cannot 'reserve space'.
UPDATE: To answer your comment, here is the solution you might be looking for
The button element is inline. To get the desired behavior you can set display:inline-block.
Check here
Try to add following to the parent div:
overflow: hidden
I hope it helps!

Margin-top not behaving as expected

I created this quick jsfiddle project to help you help me.
Why does margin-top for #container push the entire body downwards from html when I expect it to push #container from #containerWrapper ?
The idea is to have all the content inside container which would be placed with a margin right under the menu.
This is caused by margin-collapse which happens to two adjacent margins. The inner margin will collapse into the outer one and behaves like the one on the outer container block.
If you want to only apply margin on #containerWrapper, you could either use padding-top or put a border between #containerWrapper and its outer block container.
For that Purpose ,You may use padding-top

Div collapses horizontally to width of widest inner element

I am having an issue with collapsing divs in CSS! But not the normal issue. That would be too easy. I have a left floating div which contains two left floated divs. The first of the left floated divs contains text. If the second inner floated div's style is empty, everything works fine and the outer div encompasses the text and both inner divs. What i need to do is set the width of the second div to 10px. Instantly when I do this the outer div collapses to 10px, squishing the text div down. What!? I am able to find some reference to this behaviour existing, but nothing comprehensive about what it is really and now to work around it.
Do you mean to clear the floats? you can overflow:hidden; zoom:1 if the element containing the floats isn't already a float, or if it already isn't somehow clearing them.
It would help if you jsfiddle.net it.

margin-bottom property of a div's last element doesn't "extend" the div

I have an element in a div, which has a background image. Below the div I have another div with another background image. Now the problem is that if the last element contained in the first div has margin-bottom applied there will be a gap between the 2 divs like this:
Screenshot http://img40.imageshack.us/img40/5603/littlesnapperh.png
Notice the gray gap caused by the margin-bottom property of the h2 element contained within the first div. I know this can be solved if I switch margin-bottom to padding-bottom but what if I need margin-bottom?
How to fix this?
This is a feature known as collapsing margins. See: http://www.w3.org/TR/CSS2/box.html#collapsing-margins
The easiest way around (aside of replacing the margin with padding as you suggest) is to add a small (1px) invisible border or padding to the outer element.
Probably something to do with overflow:hidden or one of the elements not clearing properly. If add overflow:hidden to the first div it might fix it.