W3C home > Mailing lists > Public > www-style@w3.org > July 2014

Re: [css-box] margin-collapse property

From: Alan Gresley <alan@css-class.com>
Date: Thu, 31 Jul 2014 00:25:59 +1000
Message-ID: <53D90077.3070701@css-class.com>
To: Jonathan Rimmer <jon.rimmer@gmail.com>, www-style list <www-style@w3.org>
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. :-/

>> 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?

> <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?

>> 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; }

>>> 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].

> [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

> Jon

Received on Wednesday, 30 July 2014 14:26:29 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:39:23 UTC