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
How to Remove Space (Margin) Above HTML Header
How Is the "Greater Than" or ">" Character Used in CSS
How to Apply Custom Animation Effect @Keyframes in Mui
IE9 + Richfaces Rendering Problem
Custom Li List-Style with Font-Awesome Icon
Bootstrap 4 Responsive Tables Won't Take Up 100% Width
Embedding Extra Styles with Noscript
How to Change the Size of a Bootstrap Checkbox
Align Two Inline-Blocks Left and Right on Same Line
Have a Fixed Position Div That Needs to Scroll If Content Overflows
How to Vertically Align 2 Different Sizes of Text
Does SCSS Support Inline Comments
Calc() Alternative to Fixed Side Bar with Content
How to Create a Sticky Footer That Plays Well with Bootstrap 3
Using :Before CSS Pseudo Element to Add Image to Modal
How to Fade In/Out Multiple Texts Using CSS/Jquery Like on Droplr