Reputation: 939
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 :)
Upvotes: 5
Views: 148
Reputation: 105886
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.
Upvotes: 1
Reputation: 11440
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
Upvotes: 1
Reputation: 22742
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).
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.
Upvotes: 1