Search code examples
cssmargin

What does collapsing width height and margin mean for block level elements?


What does it mean that the width of block level elements can not be collapsed but the height can?

And can you please explain this text from the W3.org specification:

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

The meaning of the word collapse is causing much of the confusion here.


Solution

  • A collapsed margin is the name given to the instance when margins of two different elements occupy the same space.

    Consider the following example:

    .box {
      height: 50px;
      width: 50px;
    }
    
    .box1 {
      background: red;
      margin-bottom: 25px;
    }
    
    .box2 {
      background: blue;
      margin-top: 50px;
    }
    <div class="box box1"></div>
    <div class="box box2"></div>

    It's difficult to tell, but that whitespace between the two boxes is only 50px. You might think it should be 75px, because I've specified a margin-bottom of 25px on the top box, and a margin-top of 50px on the bottom box. 25 + 50 = 75, so why is the whitespace only 50px?

    Well, margins can't have any content within them; a margin is specifically denoting a lack of content. Considering there is no content to display in a margin, the parser thinks they might as well be combined to optimise space.

    The word 'collapsed' comes about because there are technically two different 'segments' of margins existing in the same place at the same time, 'collapsing' in on each other.

    Note that this doesn't happen with margin-left and margin-right:

    .box {
      height: 50px;
      width: 50px;
      float: left;
    }
    
    .box1 {
      background: red;
      margin-right: 25px;
    }
    
    .box2 {
      background: blue;
      margin-left: 50px;
    }
    <div class="box box1"></div>
    <div class="box box2"></div>

    The space above is indeed 75px. This can be a confusing concept to wrap your head around, but it's important to note that it only affects vertical margins. Further information about collapsing margins can be found at CSS Tricks and Mozilla.

    It's also important to note that, by default, a block-level element takes up 100% of the width of its parent, but 0% of the height.

    Here's an example illustrating this:

    .parent {
      background: blue;
      border: 10px solid purple;
      height: 50px;
      width: 200px;
    }
    
    .child {
      background: red;
    }
    <div class="parent">
      <div class="child">Text</div>
    </div>

    In the above example, I specify both a width and a height on the parent, though I don't specify either on the child. As you can see, the child element inherits the 200px width, but does not inherit the 50px height.

    Hopefully this helps clarify that a bit!