For What Reason Margin Collapse Rules Were Introduced in CSS

For what reason margin collapse rules were introduced in CSS?

This is one of the situations where it doesn't really make sense until you realise that the alternatives make less sense.

As you probably know, margins specify the distance between elements, it's not an "outer padding" that surrounds each element. If two elements with the margin 20px are next to each other, the distance between them is 20px, not 40px.

As the margin is a distance to another element, it makes sense that the distance is from the element to the surrounding elements, not to the boundary of the parent element.

If the margin would be counted to the boundary of the parent element, putting elements in a div element would introduce extra spacing between the elements eventhough the div itself has no margin or padding. The margins around an element should remain the same if you add an unstyled div around it.

What is the means of margin collapse ?

It's not a problem, it's a design decision. It means: when adjacent elements have margins that "touch", the two margins are collapsed into the same space. So for example:

_____
| A | Element A has 20-px bottom margin
|___|

<-- space between elements is 20, not 40
_____
| B | Element B has 20-px top margin
|___|

The margins are "collapsed" together. The CSS specification requires browsers to behave this way by design. It is actually a Good Thing and helpful, once you understand when and how it is happening.

Why no rule for un-collapsing margins

No, there are numerous other ways, including floating, clearance, absolute positioning, setting overflow to values other than visible, setting a certain min-height, etc, which you can determine based on what the spec says.

But you're right in that all of these are workarounds with various side effects and disadvantages, and there is no true "off switch" available in CSS like margin-collapse, not even in the CSS3 Box Model module. A possible rationale is that margin collapse is supposed to happen naturally, and therefore the only way it can be prevented is as a side effect, but that's just my guess, as I agree there are several cases where it isn't intuitive or appropriate.

That said, if you're feeling adventurous you could make a suggestion on the www-style mailing list, and see what they say. I don't think you're going to have much luck, though.

What is the point of CSS collapsing margins?

The general meaning of "margin" isn't to convey "move this over by 10px" but rather, "there must be 10px of empty space beside this element."

I've always found this is easiest to conceptualize with paragraphs.

If you just gave paragraphs margin-top: 10px and had no margins on any other elements, a series of paragraphs would be spaced beautifully. But of course, you'd run into trouble when placing another element underneath a paragraph. The two would touch.

If margins didn't collapse, you'd hesitate to add margin-bottom: 10px to your previous code, because then any pair of paragraphs would get spaced 20px apart, while paragraphs would separate from other elements by only 10px.

So vertical margins collapse. By adding top and bottom margins of 10px you're saying, "I don't care what margin rules any other elements have. I demand at least 10px of padding above and below each of my paragraphs."

Collapsed margin in CSS

The margins of #empty collapse through, resulting in a 20px collapsed-through margin. This collapsed-through margin collapses with the 10px bottom margin of the first paragraph, and the 10px top margin of the last paragraph. This results in a 20px gap between the first and last paragraphs, since the collapsed-through margin is larger than either of their margins and therefore swallows them both.

Your observation is correct: #empty, when its collapsed through, is rendered with its top margin. From the spec:

  • [...] The position of the element's top border edge is the same as it would have been if the element had a non-zero bottom border.

Note that the positions of elements that have been collapsed through have no effect on the positions of the other elements with whose margins they are being collapsed; the top border edge position is only required for laying out descendants of these elements.

The position that "would have been if the element had a non-zero bottom border" is the position of the element if the element's margins did not collapse through, since having a non-zero bottom border blocks the margins from collapsing through.

Why does Margin Collapsing only apply to top and bottom but not left and right

Only block level elements can have their margin collapsed and if they are block level elements, they cannot have elements to their left or right.

See the following link for more information: Why horizontal margin doesn't collapse as vertical margin?

Hope this helps.

Why does -webkit-margin-collapse take the smallest value when there is an h1 inside of the body tag?

In quirks mode, margin collapsing behaves differently in a variety of situations. In your example, the default top margin of any first child of body that has default margins, such as p or h1, will be ignored. I believe Chrome implements this behavior via the -webkit-margin-collapse property (as mentioned in your title); Firefox instead zeroes out the top margin of most body > :-moz-first-node elements (see quirk.css).

You'll see the expected behavior when you include a DOCTYPE.

Why are margins not collapsing?

Flex items' margins won't collapse. When flex items wrap, they create their own row, and the individual margins on the flex items won't collapse between rows. Only normal, adjacent block elements stacked will margin collapse the way you're intending. This is a good reference - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

You can create the same layout by removing the top margin from the li's and making that a padding-top on the ul instead, then only the bottom margin will be applied between li's when the flex row wraps.

ul {  list-style-type: none;  padding-left: 0px;}
a { text-decoration: none;}
main { background-color: #F1F4F5; padding: 30px 0px;}
.main-wrapper { max-width: 800px; margin: auto;}
.tags ul { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; margin: 0; padding-top: 20px;}.tags li { margin: 0 10px 20px; display: block;}.tags a { display: block; justify-content: center; color: #3A4250; background-color: #e6e6e6; border-radius: 20px; padding: 7px 20px; transition: background-color 0.3s ease, color 0.3s ease;}.tags a:hover { color: #FFFFFF; background-color: #FC575E; transition: background-color 0.3s ease, color 0.3s ease;}
<main>  <div class="main-wrapper">    <div class="tags">      <ul>        <li>          <a href="#">ELEMENT 1</a>        </li>        <li>          <a href="#">ELEMENT 2</a>        </li>        <li>          <a href="#">ELEMENT 3</a>        </li>        <li>          <a href="#">ELEMENT 4</a>        </li>        <li>          <a href="#">ELEMENT 5</a>        </li>      </ul>    </div>  </div></main>


Related Topics



Leave a reply



Submit