Margin collapsing in flexbox

CssFlexbox

Css Problem Overview


Typically, in CSS, when a parent and its last child have a margin, the margins collapse to create a single margin. E.g.

article {
  margin-bottom: 20px
}

main {
  background: pink;
  margin-bottom: 20px;
}

footer {
  background: skyblue;
}

<div id="container">
  <main>
    <article>
      Item 1
    </article>
    <article>
      Item 2
    </article>
  </main>
  <footer>Footer</footer>
</div>

As you can see, even though a margin of 20px is specified on both the article and the main tags, you only get a 20px margin between the last article and footer.

When using flexbox, however, we get a 40px margin between the last article and footer — a full 20px margin from the article to main, and another 20px from main to footer.

#container {
  display: flex;
  flex-direction: column;
}

article {
  margin-bottom: 20px
}

main {
  background: pink;
  margin-bottom: 20px;
}

footer {
  background: skyblue;
}

<div id="container">
  <main>
    <article>
      Item 1
    </article>
    <article>
      Item 2
    </article>
  </main>
  <footer>Footer</footer>
</div>

Is there a way to make flexbox margins behave the same way as the non-flexbox ones?

Css Solutions


Solution 1 - Css

Margin collapsing is a feature of a block formatting context.

There is no margin collapsing in a flex formatting context.

> 3. Flex Containers: the flex and inline-flex display > values > > A flex container establishes a new flex formatting context for its > contents. This is the same as establishing a block formatting context, > except that flex layout is used instead of block layout. For example, > floats do not intrude into the flex container, and the flex > container’s margins do not collapse with the margins of its contents.

Solution 2 - Css

though margin collapse is not possible with flexbox, you can use gap to achieve the same result:

.parent {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    column-gap: 5px;
    row-gap: 15px;
      
    max-width: 70px;
    outline: 1px solid #440;
}

.parent > div {
    background: #8ff;
    width: 20px;
    height: 20px;
}

<div class="parent">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>

https://coryrylan.com/blog/css-gap-space-with-flexbox

Solution 3 - Css

NOTE: This is not a way to make margins behave in a flex box layout the same way as they do in a block layout; however, this may help resolve the margin problem in some cases.

Instead of relying on collapsing margins, you can use pseudo selectors to get the effect you want:

main{
  display: flex;
  flex-direction: column;
  margin-bottom: 20px;
}

article{
  margin-bottom: 20px;
  background: #eee;
}

article:last-child{
  margin-bottom: 0;
}

footer{
  background: #eef;
}

<main>
  <article>
    This is article number 1
  </article>
  <article>
    This is article number 2
  </article>
  <article>
    This is article number 3
  </article>
</main>
<footer>
  This is the footer of the page
</footer>

Solution 4 - Css

margin-trim is likely to be added to the css specifications, which will deal with these type of situations. More details are found in the https://developer.mozilla.org/en-US/docs/Web/CSS/margin-trim. Browser support can be viewed here: https://caniuse.com/mdn-css_properties_margin-trim

Solution 5 - Css

The accepted answer explains why it doesn't work, but does not provide a solution. Here's a way to make the flexbox elements align just like the non-flexbox example.

#container {
  display: flex;
  flex-direction: column;
}

main {
  background: pink;
  margin-bottom: 20px;
}

main > article + article {
  margin-top: 20px
}

footer {
  background: skyblue;
}

<div id="container">
  <main>
    <article>
      Item 1
    </article>
    <article>
      Item 2
    </article>
  </main>
  <footer>Footer</footer>
</div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCoffee BiteView Question on Stackoverflow
Solution 1 - CssMichael BenjaminView Answer on Stackoverflow
Solution 2 - CssoriadamView Answer on Stackoverflow
Solution 3 - CssTrevorView Answer on Stackoverflow
Solution 4 - CssivanjiView Answer on Stackoverflow
Solution 5 - CssmarcvangendView Answer on Stackoverflow