5

I always thought the underlying theory behind css margins was very simple. A div with a margin of 10px will create a 10px cushion around that element. When two divs are placed side by side, both with a 10px margin, it results in the divs being 20px apart; both elements have a 10px margin, resulting in 20px distance between the elements. This seems to be correct, and is what I have always believed as fact.

HOWEVER, I have recently discovered that if instead of the two divs being side by side, and place one under the other, the margin between the two elements is now only 10px. What happened to 10px margin given off by the other div? Why isn't there consistency between side by side and vertically stacked?

A margin essentially says "don't put anything within x pixels of me". By "anything", does this include the margins of other elements? In the case of side by side, the answer seems to be yes, the margin says "don't put anything, including your own margin, within x pixels of me". In the case of vertically, it seems to allow the latter?

Please can someone clarify so I can put it to bed and continue with my evening :)

Alex
  • 909
  • 1
  • 8
  • 12
  • Could you provide an example? I don't think I've ever witnessed this behavior. – Zeta Jul 26 '12 at 19:05
  • 1
    An example of your code would be helpful, both the HTML and CSS. – Diodeus - James MacFarlane Jul 26 '12 at 19:06
  • 1
    Possible duplicate: http://stackoverflow.com/questions/3906640/css-margins-overlap-problem – DACrosby Jul 26 '12 at 19:08
  • Oh my god he's right :o http://dabblet.com/gist/3183884 – Madara's Ghost Jul 26 '12 at 19:10
  • Ah thanks Douglas - your link eventually routed me to here http://www.w3.org/TR/CSS21/box.html#collapsing-margins It explains the theory of collapsible margins: vertically adjoined margins always collapse, forming just one margin. However, horizontally aligned margins do not collapse. I haven't read the exact reason yet, but this is certainly new to me – Alex Jul 26 '12 at 19:13
  • Yes Truth, see what happens when you enter display:inline; to the div – Alex Jul 26 '12 at 19:14
  • Also check http://jsfiddle.net/Z2nUN/4/ to see how different display styles affect it - apparently `display:inline-block` adds the margins together – DACrosby Jul 26 '12 at 19:24
  • @Truth: [CSS3 box](http://www.w3.org/TR/css3-box/#collapsing-margins) dictates that it depends on `block-progression`, which was in [CSS3 text module](http://www.w3.org/TR/2003/CR-css3-text-20030514/). It was removed in the 2005 version and shall be introduced in "CSS3 Text Layout Module. (forthcoming)" (last update 2007). Sometimes CSS3 and its modules make me feel like I want to get the [permit A 38](http://en.wikipedia.org/wiki/The_Twelve_Tasks_of_Asterix#The_Twelve_Tasks). – Zeta Jul 26 '12 at 19:51

3 Answers3

1

It has to do with when they're inline or inline-block it changes their property so that they stack next to each other without collapsing the margins together (which is normal, but unintuitive behavior).

http://jsfiddle.net/xeCZJ/3/

Margins collapse when they're at the default display:block property. You can use inline-block to make them behave as you expect, but you have to manually control the linebreaks with br or with the width of the containing element.

Or you can use padding instead of margins.

brentonstrine
  • 21,694
  • 25
  • 74
  • 120
  • Your margin for the `display:inline` and `display:block` appear to be the same height in the output. I don't see the difference you're saying. I tried it as well, `display:inline` seems to make no margin work (as you said, need padding instead). http://jsfiddle.net/Z2nUN/2/ – DACrosby Jul 26 '12 at 19:19
  • Look at the difference between the `block` and `inline-block` with linebreaks.(Simpler example: http://jsfiddle.net/xeCZJ/4/) The `inline-block` doesn't collapse the margins, but you have to force it to go down to the next line somehow. For `inline` there is no vertical margins, but you can tell the horizontal distance is 40px, not 20px. – brentonstrine Jul 26 '12 at 19:20
  • http://jsfiddle.net/Z2nUN/4/ Fair enough, `display:inline-block` seems to add both margins together and does not collapse them. – DACrosby Jul 26 '12 at 19:23
1

Looks like display:inline ignores all top/bottom margins, display:block allows the margins to collapse, and display:inline-block adds them together for a massive margin. Checkout this jsFiddle for example : http://jsfiddle.net/Z2nUN/4/

<p>Some content</p>
<p>some more content</p>
<p class="wideMargin">some more extra content</p>
<p class="narrowMargin">less extra content</p>
<p>Some content</p>
<p>some more content</p>
<p class="wideMargin">some more extra content</p>
<p class="narrowMargin">less extra content</p>

<hr />
<div class="allBlock">
<p>Some content</p>
<p>some more content</p>
<p class="wideMargin">some more extra content</p>
<p class="narrowMargin">less extra content</p>
</div>

<hr />
<div class="allInlineBlock">
<p>Some content</p>
<p>some more content</p>
<p class="wideMargin">some more extra content</p>
<p class="narrowMargin">less extra content</p>
<p>Some content</p>
<p>some more content</p>
<p class="wideMargin">some more extra content</p>
<p class="narrowMargin">less extra content</p>
</div>​


p{ margin:10px; background:#ccc; display:inline;}
.wideMargin{ margin:30px;}
.narrowMargin{ 0px; }
.allBlock p{ display:block;}
.allInlineBlock p{ display:inline-block;}​

Never noticed that. Today I learned, I guess.

EDIT: Added display:block and inline-block

DACrosby
  • 11,116
  • 3
  • 39
  • 51
1

It seems you found the answer yourself: collapsing margins are part of the CSS2.1 recommendation and CSS3 working draft. The latter depends on block-progression, which is 'tb' (top -> bottom) by default. This will result in only top-/bottom-margins collapsing. In order to collapse left-/right-margins, one would have to use block-progression:lr or block-progression:rl:

  • The left margin of a box A collapses with the left margin of its parent box B if the margins are adjoining and B is ‘rl’ or ‘lr’.
  • The right margin of a box A collapses with the right margin of its parent box B if the margins are adjoining and B is ‘rl’ or ‘lr’.

Unfortunately block-progression isn't in the newest working draft and is very unlikely to be implemented by any browser. The CSS3 box module hasn't been updated since 2007, so it's not clear when you'll get a definite answer.

Zeta
  • 103,620
  • 13
  • 194
  • 236
  • As a side note, I actually prefer a world where they don't collapse. This seems more logical to me, and easier to visualise when planning layouts. An option to prevent the collapsing top->bottom seems preferable to an option to collapse them left->right – Alex Jul 26 '12 at 19:50
  • @Alex: If you're working with planned layouts its often a better idea to use absolute or relative positioning instead of margins, especially since absolute positioned elements' margin will never collapse. – Zeta Jul 26 '12 at 20:02