0

The following matter occurs in Chr and FF on Win, and in Saf on iOS, so it's probably not a browser bug.

I have a #titleDiv inside a #container inside a #grandContainer. Here is the code (ignore the invalidated declarations for now):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Margin-top demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
    box-sizing: border-box;
}
body {
    background-color: pink;
}
#grandContainer {
    height: 100vh;
    max-height: 1333px; /* The height of the background photo. */
    max-width: 2000px; /* The width of the photo. */
    margin: 0 auto; /* For the centering. Mind the margin-top: 0. */

    background: url(https://www.freecodecamp.org/news/content/images/size/w2000/2021/07/kobu-agency-ipARHaxETRk-unsplash.jpg);
    background-position: center center;
    background-size: cover;
    background-repeat: no-repeat;
    over/flow: hidden;
    /* Invalidated, the margin-top:100px of the #titleDiv is applied to the #grandContainer?? */
    bor/der: 1px solid black; /* Ditto. */
}
#container {
    over/flow: hidden; /* Ditto. */
    bor/der: 1px solid black; /* Ditto. */
}
#titleDiv {
    margin-top: 100px;
    text-align: center;
    font-size: 3em;
    border: 1px dashed black;
}
</style>
</head>
<body>
    <div id="grandContainer">
        <div id="container">
            <div id="titleDiv">Website Title</div>
        </div>
    </div>
</body>
</html>

And here is the matching Codepen: https://codepen.io/FrankConijn/pen/WNMWKGP.

As you can see, I gave the body a background: pink and the titleDiv a margin-top: 100px. I expected this: enter image description here

But what I got was this: What I got

To get the expected rendering, I had to give either the grandContainer or the container an overflow: hidden(!) or a border (revalidate one of the four by removing the slash in the Codepen). I know a thing or two about CSS, but why is that? There have been a number of questions asked and answered about collapsing margins, and I understand that principle. But this is different, as far as I can see.

  • That's due to margin collapsing. You can add `display: flow-root;` on your `#container`, which will have the least impact on the rest of the behavior. – t.niese Jun 19 '22 at 12:49
  • [How to disable margin-collapsing?](https://stackoverflow.com/questions/19718634/how-to-disable-margin-collapsing), [What is the point of CSS collapsing margins?](https://stackoverflow.com/questions/3069921/what-is-the-point-of-css-collapsing-margins) – t.niese Jun 19 '22 at 12:51
  • @t.niese -- Thanks for a better remedy. But this is not a matter of collapsing margins, as far as I can see. There is no margin that disappears or gets less. The `margin-top: 100px` of the titleDiv is applied to the grandContainer. Why is that? – Frank Conijn - Support Ukraine Jun 19 '22 at 12:54
  • `The margin-top: 100px of the titleDiv is applied to the grandContainer.` that due to margin collapsing. The top margin of the `grandContainer` collapse with the one of `container` and then with `titleDiv`, because those are the first child elements. The largest top margin of all three elements is used and applied to `#grandContainer`. – t.niese Jun 19 '22 at 13:02
  • This is margin collapse, check the second case in which this occurs https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing – bryan60 Jun 19 '22 at 13:04
  • @t.niese -- I would call that 'stacked margins' or 'transferred margins' then, or 'margin hierarchy'. And I'm afraid I still don't understand the logic behind it? I find it totally unlogical. Especially the cure of giving one of the two a border?? – Frank Conijn - Support Ukraine Jun 19 '22 at 13:04
  • Margin collapsing however does not happen if a new block formatting context is introduced. Which e.g. `overflow: hidden` and `display: flow-root` do. – t.niese Jun 19 '22 at 13:04
  • @bryan60 -- Thanks for link. I'll study that page this evening. – Frank Conijn - Support Ukraine Jun 19 '22 at 13:06
  • there are a lot of ways to solve this, they all come down to the same thing, margin isn't used to space a child from it's parents top. – bryan60 Jun 19 '22 at 13:13
  • Not sure if I oversimplified the margin collapsing rules, or missed edge cases. But you can it see that way, the top margin describes the minimum distance to the bottom of its previous sibling, if that does not exist, the next previous sibling of the closest ascendant. Or if an ascendant is reached that creates block formatting context to the top of that. If multiple elements share the same element to which the top margin describes the minimum distance, the margin of those elements is collapsed. – t.niese Jun 19 '22 at 13:44
  • @bryan60 — That MDN page made it clear to me, indeed. I always thought that the collapsing-margin issue was just a matter of overlapping margins of adjacent siblings being left overlapping, rather than being added up. However, there's more to it. I still find it a bizarre rendering in my example (and the second on the MDN page), but the `display: flow-root` is a good remedy. Even though for iOS < 13 we still need one of the other remedies. Thanks, also to t.niese. – Frank Conijn - Support Ukraine Jun 19 '22 at 19:09
  • you could just use padding on the parent? – bryan60 Jun 19 '22 at 20:15
  • @bryan60 — Maybe I could, but I didn't know that that worked as well. When making a layout, I generally give all important elements a border temporarily. And when I removed the last one, suddenly my layout was very different. That's how I found out about the border remedy. And I learned about the overflow remedy after Firefox's DevTools indicated that the grandContainer had overflow. – Frank Conijn - Support Ukraine Jun 20 '22 at 20:31

0 Answers0