- From: Jonathan Rimmer <jon.rimmer@gmail.com>
- Date: Wed, 30 Jul 2014 15:49:41 +0100
- To: Alan Gresley <alan@css-class.com>, www-style list <www-style@w3.org>
On 2014-07-30 15:25, Alan Gresley wrote: > On 30/07/2014 11:46 PM, Jonathan Rimmer wrote: >> >> On 2014-07-30 13:14, Alan Gresley wrote: >>> On 30/07/2014 8:15 PM, Jon Rimmer wrote: >>>> The box-sizing property has proven very popular as a way for >>>> developers to control unintuitive default behaviour in CSS, to the >>>> extent that many (most?) CSS frameworks such as Bootstrap include a >>>> global box-sizing: border-box override by default. >>>> >>>> I believe it would be useful to provide a similar switch to control >>>> margin-collapse behaviour. The default behaviour is useful in some >>>> contexts, but in others, particularly collapsing margins between >>>> parents and children, it is often just a pain. To that end, I >>>> propose a new property margin-collapse that controls whether an >>>> element is eligible for margin-collapsing. Between eligible elements, >>>> margin collapsing would proceed as per the rules defined in CSS 2.1. >>>> >>>> The margin-collapse property would accept the following values: >>>> >>>> inherit Inherit from parent. Mixing with any other value is invalid. >>>> >>>> all Default value. Eligible for collapse with adjacent, parent and >>>> child elements that are eligible for collapsing. Mixing with any >>>> other value is invalid. >>>> >>>> none Do not collapse with any other element. Mixing with any other >>>> value is invalid. >>>> >>>> adjacent Eligible for collapse with adjacent elements that are >>>> eligible for collapsing. >>>> >>>> parent Eligible for collapse with parent elements that are eligible >>>> for collapsing. >>>> >>>> children Eligible for collapse with first and last child elements >>>> that are eligible for collapsing. >>>> >>>> The final three values would be combinable, e.g. >>>> >>>> .nestable { margin: 1em 0; margin-collapse: parent children; } >>> >>> Ok, why have you got vertical margin in this declaration as a >>> shorthand when vertical margin do not collapse? >> I don't follow. Vertical margins do collapse[1], and in this example the >> elements margin-collapse is configured to be eligible for collapse with >> parent and child elements in the DOM, just not adjacent elements. > > Oh, I should have said horizontal margins. :-/ > OK, well I included the horizontal = 0 to emphasise that the margins in question were the vertical ones >>> Secondly, where should my <p> be position in the following test? >>> >>> <style type="text/css"> >>> .wrapper { background: yellow; } >>> .float { >>> float: left; >>> width: 100px; >>> height: 100px; >>> background: blue; >>> margin-bottom: 20px; >>> } >>> p { border: 5px solid red; } >>> p.test1 { margin-collapse: all; } >>> p.test2 { margin-collapse: none; } >>> .box, .wrapper { clear: left; } >>> </style> >>> >>> <p>A paragraph</p> >>> <div class="float"></div> >>> <p class="test1">Where should I be positioned with 'margin-collapse: >>> all'?</p> >>> >>> <div class="wrapper"> >>> <div class="float"></div> >>> <p class="test2">Where should I be positioned with 'margin-collapse: >>> none'?</p> >>> </div> >>> >> See this illustration: http://i.imgur.com/pBTPefE.png >> >> The first <p> would appear as the first element in the page, with its >> default 1em margin. >> <p.test1> would appear exactly as it does under the current rules: It >> would be flush with the top of the first <div.float>. Its top margin >> would collapse with that of the first <p>. > > What about the <div.float>? It will still be 1em below the first > paragraph? Sure, neither it or the first paragraph have any margin-collapse set, so they are still eligible for margin-collapse, so follow the same behaviour as in CSS 2.1. >> <p.test2> is ineligible for collapse, so its top margin would be added >> to that of the first <div.float> above it. It would appear 1em below >> that element. > > Then does that mean that the float is now sitting 1em above it's > containing block? No? Its containing block is <div.wrapper>, not <p.test2>. >>> Also what happens in this situation? >>> >>> <style type="text/css"> >>> .wrapper { background: yellow; margin-collapse: none; } >>> p { border: 5px solid red; } >>> p.test1 { margin-collapse: all; } >>> </style> >>> >>> >>> <div class="wrapper"> >>> <p class="test2">Which margin-collapse win?</p> >>> </div> >>> >> <p.test2>'s margin would not collapse with the wrapper. The >> <div.wrapper> has declared that its margins are ineligible for >> collapsing. The <p.test2> has declared that it is eligible for >> collapsing, but its margins cannot collapse with an ineligible element. > > What about if I swap the style like so? > > <style type="text/css"> > .wrapper { background: yellow; margin-collapse: all; } > p { border: 5px solid red; } > p.test1 { margin-collapse: none; } > </style> > Same result. The <div.wrapper>'s margins are now ineligible for collapse, but the <p.test>'s margins aren't. Since both elements involved in a margin collapse have to 'agree' to the collapse, they can't be collapsed here. The idea of the margin-collapse property isn't to say whether an element's margins definitely *will* collapse, just to say that they *can*. E.g. that the user agent's margin collapse algorithm can consider for them for collapse. In each case, *both* elements would have to eligible for collapse before a collapse between their margins was considered. And even if the are both eligibile, they still follow the old rules from CSS 2.1. >>>> There could also be separate properties margin-collapse-top and >>>> margin-collapse-bottom for controlling the collapse behaviour of the >>>> relevant margins. >>>> >>>> The primary use case for this property would be for container >>>> elements that do not want their children's margins to collapse with >>>> their own: >>> >>> That is a used case for a property and value for a 'Block Formatting >>> Context'. >> I don't understand what you're saying here. > > Margins of elements that establish new block formatting contexts (such > as floats and elements with 'overflow' other than 'visible') do not > collapse with their in-flow children [2]. Right, yeah, so there are rules in CSS 2.1 around which elements can collapse with each other. The idea of this property wasn't to replace them, just to add a mechanism for a user to say, should this element's margins even be eligible for collapse with other elements? And if so, which elements? Just adjacent DOM nodes? Just parent and children nodes? Etc. I think it is useful to have an explicit way to control this, without the side effects of floating or setting overflow on an element. >> [1] https://developer.mozilla.org/en-US/docs/Web/CSS/margin_collapsing > > 2. > http://www.w3.org/TR/2011/REC-CSS2-20110607/box.html#collapsing-margins > > Alan Jon
Received on Wednesday, 30 July 2014 14:50:12 UTC