|
From: Andy Dingley on 23 Jan 2008 12:44 Does anyone grok browser variations for collapsing vertical margins, and which is correct behaviour? Embed <div> inside <div>. Place padding on the outer <div>, margin on the inner <div>. Should vertical margins between inner <div>s collapse? Should such a vertical margin before the _first_ <div> collapse? IE does, FF doesn't. I need to do a "gridded" layout (in graphic design terms) which means one or two design elements within an overall coloured block, and maintaining a gutter between them, and inside the overall dimensions of the block. Yes, it's all paper-based guff, but I'm trying to translate corporate marketing-speak into web design 8-( What I really need is some bulletproof CSS that I can then let a whole bunch of HTML coders loose on. So I need stability, simplicity and cross-browser consistency. Am I best shooting for margins (on the inner) here, or padding (on the outer)? Relevant spec: CSS 2.1 specification: 8.3.1 Collapsing margins http://www.w3.org/TR/CSS21/box.html#collapsing-margins Demo example: http://codesmiths.com/dingbat/lj/usenet/collapsing_vertical_margins/ Thanks for any comments. Apologies for not doing all my own research, but I'm really out of time tonight. 8-(
From: Ben C on 23 Jan 2008 13:16 On 2008-01-23, Andy Dingley <dingbat(a)codesmiths.com> wrote: > Does anyone grok browser variations for collapsing vertical margins, > and which is correct behaviour? > Embed <div> inside <div>. Place padding on the outer <div>, margin on > the inner <div>. Should vertical margins between inner <div>s > collapse? You've only got one inner <div> so I don't really understand the question. But the inner div's top margin won't collapse against the top margin of its container if the container has top padding (or border). Otherwise it should. > Should such a vertical margin before the _first_ <div> collapse? IE > does, FF doesn't. Which is the first div? OK, I found the URL: > Demo example: > http://codesmiths.com/dingbat/lj/usenet/collapsing_vertical_margins/ The inner box's margins should not collapse with its container's padding! Firefox is rendering it correctly. Haven't looked at IE, but if it doesn't look the same as Firefox, it's wrong. In other words there should 0.6in of fresh air between the bottom of the red border at the top and the top of the yellow border at the bottom. This is the green box in the bottom right I'm talking about. > I need to do a "gridded" layout (in graphic design terms) which means > one or two design elements within an overall coloured block, and > maintaining a gutter between them, and inside the overall dimensions > of the block. Yes, it's all paper-based guff, but I'm trying to > translate corporate marketing-speak into web design 8-( > > What I really need is some bulletproof CSS that I can then let a whole > bunch of HTML coders loose on. So I need stability, simplicity and > cross-browser consistency. Am I best shooting for margins (on the > inner) here, or padding (on the outer)? I suppose padding may be less likely to exercise browser bugs as margin collapsing is tricky to get right. > Relevant spec: > CSS 2.1 specification: 8.3.1 Collapsing margins > http://www.w3.org/TR/CSS21/box.html#collapsing-margins > > Demo example: > http://codesmiths.com/dingbat/lj/usenet/collapsing_vertical_margins/ > > > Thanks for any comments. Apologies for not doing all my own research, > but I'm really out of time tonight. 8-( As for the non-float after a float, what you're seeing there is not margin-collapsing, but a consequence of the fact that "clear" generates enough clearance to get the top _border_ of the cleared box underneath the floats. (See 9.5.2 CSS 2.1). As 9.5.2 explains the browser is supposed to do margin-collapsing first, then move the box even further down if necessary to achieve clearance. In this case your 3em margin is probably not enough to get the <p> below the floats, so it effectively disappears. However Firefox is not perfect. Change that 3em top margin on the cleared <p> to 1000px and you should see some margin, but not in Firefox (or Opera or Konqueror surprisingly, making me wonder if I have interpreted the specification wrong. But it seems quite clear).
From: Andy Dingley on 24 Jan 2008 09:45 On 23 Jan, 18:16, Ben C <spams...(a)spam.eggs> wrote: > You've only got one inner <div> so I don't really understand the > question. My example has one inner <div>. Live code may have one, and will certainly also have two inner <div>s (floated alongside each other). Probably it may also a number of divs, not floated and appearing vertically in normal sequence. What I want to achieve here (ideally) is simple bulletproof CSS that can be used with simple HTML to produce the necessary. I'd like to avoid any need to mark the inner content as class="first-element" or similar. If _all_ margins (H&V) collapsed, in this context then I'd get the behaviour I need automatically, for almost no effort. 8-( As it is, it looks like I need to (for browser compatibility) always set the top margin to 0, then work from that point. The requirements of consistency first, then getting the design right. I think FF's behaviour of not-collapsing the first is the correct one, even if I'm not sure quite which rule(s) are triggering this. Is it because its parent is padded? Or because it's floated? Not what I _want_ here anyway, in this particular case, but so it goes. > I suppose padding may be less likely to exercise browser bugs as margin > collapsing is tricky to get right. The trouble with that is that I don't think I can use it to space elements apart when I'm looking at multiple siblings (unlike the single element example). > However Firefox is not perfect. Change that 3em top margin on the > cleared <p> to 1000px and you should see some margin, but not in > Firefox (or Opera or Konqueror surprisingly, making me wonder if I have > interpreted the specification wrong. But it seems quite clear). Agreed. FF's behaviour is clearly "make the border barely clear of the previous", no matter what the margins. I don't really know what IE does here. It appears to be doing much the same (i.e. it's not calculating anything inbetween), but it bases things on the outside of the box, not the outside of the border. I haven't studied the spec carefully enough to judge which is better.
From: Ben C on 24 Jan 2008 12:29 On 2008-01-24, Andy Dingley <dingbat(a)codesmiths.com> wrote: > On 23 Jan, 18:16, Ben C <spams...(a)spam.eggs> wrote: > >> You've only got one inner <div> so I don't really understand the >> question. > > My example has one inner <div>. Live code may have one, and will > certainly also have two inner <div>s (floated alongside each other). > Probably it may also a number of divs, not floated and appearing > vertically in normal sequence. Margins never collapse on floats, which may be something to bear in mind. > What I want to achieve here (ideally) is simple bulletproof CSS that > can be used with simple HTML to produce the necessary. I'd like to > avoid any need to mark the inner content as class="first-element" or > similar. I see. > If _all_ margins (H&V) collapsed, in this context then I'd get the > behaviour I need automatically, for almost no effort. 8-( How about a table with border-spacing? > As it is, it looks like I need to (for browser compatibility) always > set the top margin to 0, then work from that point. The requirements > of consistency first, then getting the design right. > > I think FF's behaviour of not-collapsing the first is the correct one, > even if I'm not sure quite which rule(s) are triggering this. Is it > because its parent is padded? Yes. See the definition of "adjoining" in CSS 2.1 8.3: An element's own margins are adjoining if the 'min-height' property is zero, and it has neither vertical borders nor vertical padding, and it has a 'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) are adjoining. In other words: if a box has padding then its first child goes inside it, underneath the padding. The child's top margin therefore starts at the bottom of the parent's top padding. The box's own margin is _above_ the padding. The margins are separated by the padding, are not adjoining, and so don't collapse. > Or because it's floated? That too. > Not what I _want_ here anyway, in this particular case, but so it > goes. > >> I suppose padding may be less likely to exercise browser bugs as margin >> collapsing is tricky to get right. > > The trouble with that is that I don't think I can use it to space > elements apart when I'm looking at multiple siblings (unlike the > single element example). Yes I see what you mean. Why not just have a series of blocks, one under the other, and give each one a top margin of 50px and a bottom margin of 50px. Then you'll get the effect of border-spacing with 50px at the very top and the very bottom and a 50px gap between each block. Of course these blocks can't be floated (or their margins won't collapse, which you want). But they can be nested inside floats. So one float for each column, with normal-flow blocks inside it to do the rows. To do spacing between columns you'll need 50px left margin on the first column, 50px right margin on the last one, and 25px for all the other left and right margins in between. Don't set padding on anything. The fact that the containers are floats will prevent their margins collapsing with the boxes inside them. >> However Firefox is not perfect. Change that 3em top margin on the >> cleared <p> to 1000px and you should see some margin, but not in >> Firefox (or Opera or Konqueror surprisingly, making me wonder if I have >> interpreted the specification wrong. But it seems quite clear). > > Agreed. FF's behaviour is clearly "make the border barely clear of the > previous", no matter what the margins. > > I don't really know what IE does here. It appears to be doing much the > same (i.e. it's not calculating anything inbetween), but it bases > things on the outside of the box, not the outside of the border. That sounds like it's also wrong, but in a different way. > I haven't studied the spec carefully enough to judge which is better. You should apply the box's top margin, collapsing it against any margins it adjoins, and then add any extra offset you need to bring the box's top border edge clear of any floats. Firefox's behaviour only breaks in relatively unusual cases-- where the collapsed top margin of the cleared block exceeds the clearance amount.
From: Gus Richter on 25 Jan 2008 18:48
Ben C wrote: > On 2008-01-23, Andy Dingley <dingbat(a)codesmiths.com> wrote: >> Does anyone grok browser variations for collapsing vertical margins, >> and which is correct behaviour? >> Demo example: >> http://codesmiths.com/dingbat/lj/usenet/collapsing_vertical_margins/ >> > As for the non-float after a float, what you're seeing there is not > margin-collapsing, but a consequence of the fact that "clear" generates > enough clearance to get the top _border_ of the cleared box underneath > the floats. (See 9.5.2 CSS 2.1). > > As 9.5.2 explains the browser is supposed to do margin-collapsing first, > then move the box even further down if necessary to achieve clearance. > > In this case your 3em margin is probably not enough to get the <p> below > the floats, so it effectively disappears. > > However Firefox is not perfect. Change that 3em top margin on the > cleared <p> to 1000px and you should see some margin, but not in > Firefox (or Opera or Konqueror surprisingly, making me wonder if I have > interpreted the specification wrong. But it seems quite clear). It seems that <p style="clear: both;..."> does not clear properly for Firefox. It does work properly if the clear is removed and just prior to the <p> a clearing div is inserted a la <div style="clear:both;"></div> -- Gus |