Vertical margins do not all get added together in determining how much space to leave, Instead only the largest positive value margin and the largest negative value margin (if there is one) are used to determine the amount of space to leave. Let's look at this in more detail to see how we can work out how much space various combinations of margins will leave and what we can do if they collapse or overlap where we don't want them to.
To start with let's consider those situations where we can have adjacent margins that will form the basis for this calculation.
The first and simplest is where we have one element following another with the bottom margin on the top element being adjacent to the top margin of the bottom element.
The next most common is where you have one element nested inside another where the outer element does not have any border or padding. The margins on the inner element will then be adjacent to the corresponding margins on the outer element.
A rarer situation would be an element that has no height, padding, or borders where its top and bottom margins would be adjacent to one another as well as being adjacent to the bottom margin of the element above it and the top margin of the element below it.
Regardless of how we have the page coded so as to end up with the margins adjacent to one another the actual space that those margins produce is always calculated the same way. Basically all of the margins are allowed to overlap on top of one another so that the actual space left (assuming that none of the margins are negative) will be the largest of the margin values specified.
For example if the top element has a 50px bottom margin and the bottom element has a 75px top margin then the space the margins leave will be 75px.
If any of the margins are negative then the calculation has a second step. The largest negative margin is subtracted from the largest positive margin and the space that is left will be the difference between those two.
Let's look at some live examples. Here we have a green element nested inside a blue one (I have given the green element a height of 50 pixels, all the other heights are created by the margins that are applied). The blue element has a top margin of 10 and a bottom margin of 25 (pixels). The green element has a top margin of 20 and a bottom margin of 5. The top margin for both elements is therefore 20 (from the green element) and the bottom margin is 25 (from the blue element).
Here's the same but with one pixel of padding added to the blue element. Notice how the margins no longer collapse because they are no longer adjacent to one another.
Here's another example. This time with three elements following one another rather than being nested. The blue and green elements both have heights of 50 pixels while the red element that is between then has a height of 0 pixels. The margins on the blue and green elements are the same as in the prior example while the top and bottom margins of the red element are 75 pixels and -10 pixels respectively. This gives us a gap between the blue and green elements that is the maximum of 25, 20, and 75 (ie. 75) adjusted for the -10 giving a final space of 65 pixels.
Here's the same thing but with each of the three elements having one pixel of padding.
The gap above the red element is now the maximum of 25 and 75 while the gap below it is now 20 less 10 because these two groups of margins can no longer collapse into one another.
These examples have demonstrated what is perhaps the simplest way of controlling which margins collapse into one another and which don't. In each case the background ends up one pixel bigger in each direction when you do it this way. If you instead want the background to remain the same size you'd need to use a one pixel border instead of the one pixel padding and then set the colour of the border so it blends into what is behind it. You may of course also need to then adjust the margin sizes by one pixel as well so as to ensure that the border plus margin adds to the distance you require.
This article written by Stephen Chapman, Felgall Pty Ltd.