CSS and Negative Margins

Negative margins are special and are dealt with as follows:

1. Work out what margins are touching.
2. Ignore all negative margins.
3. Perform the collapse as if there were no negative margins.
4. Select the largest of the negative margins, and subtract it from the computed margin from step 3.

1
2
3
  <p style="margin-bottom:-5px;">A</p>
  <p style="margin-top:100px;margin-bottom:-50px;"></p>
  <p>B</p>

Step 1:

1
2
3
4
5
6
7
8
  16
  A
  -5
  100
  -50
  16
  B
  16

Step 2, ignoring the negative margins:

1
2
3
4
5
6
  16
  A
  100
  16
  B
  16

Step 3:

1
The gap between A and B is max(100,16), which is 100 pixels.

Step 4, subtracting the largest negative margin:

1
2
3
  Max(5,50) is 50
 
  100 - 50 = 50

So the resulting gap between A and B is 50 pixels.

 
Nested Margins

This is the part that causes most problems for Web developers.

1
2
3
4
5
  <div style="margin-top:10px">
  <div style="margin-top:20px">
  A
  </div>
  </div>

There are two margins touching each other: 10 and 20 pixels. The resulting margin will be max(10,20), which is 20 pixels.

The question is; where does the 20 pixels appear:

1. Before the outer DIV?
2. Before the inner DIV but inside the outer DIV?

(In other words, if the background of the outer DIV is red, and the background of the inner DIV is white, should any red be visible?)

The answer is quite simple; the resulting margin always appears as far out as possible - outside the outermost element whose margin is taking part in the collapse. Even though the margin that gets “used” is the one from the inner DIV, it appears outside the outer DIV. So it seems to appear in the wrong place.

This is the part that causes the most unexpected effects. A developer might make the background of a container white, make the background of a DIV inside it blue, then put a paragraph or heading inside it. The expectation is for the blue to extend all the way to the top of the container, but it does not. The paragraph may have a default top margin of 16 pixels, and that collapses to the outside of the DIV because it touches the 0 pixel top margin of the DIV, pushing the DIV down, and leaving a strange gap at the top of the blue.

The solution to the unwanted gap, is to make sure the margin collapse cannot happen. The way to do that is to make sure the 0 pixel top margin of the DIV and the 16 pixel top margin of the paragraph cannot touch each other. This is where the box model becomes useful. It is possible to remove the margin of the paragraph, but it is also possible to manipulate the DIV to insert something between the paragraph’s top margin, and the DIV’s 0 pixel top margin. The way to do that is to add a top padding or top border of at least 1 pixel of height onto the DIV, since they sit between the two margins.

The following example shows the situation described, with a paragraph inside a DIV that has a blue background, inside a white container (with the solid black border). The paragraph has a dashed border so you can see where it is. The white shows through because the paragraph’s margin has collapsed through and is applied to the DIV:

css-1.jpg

 
The following example shows the same situation, but with a single pixel of top and bottom padding added to the DIV. The result is two pixels taller because of the padding, but the margin remains on the paragraph, and does not collapse through to the DIV. The margin extends to one pixel away from the black border, with the remaining pixel being the DIV’s padding:

css-2.jpg

 
The following example uses a similar approach, but uses a (dotted red) border on the DIV instead of padding:

css-3.jpg

 



Pages : 1 2