margin-top only when the flex item is wrapped

CssMarginFlexbox

Css Problem Overview


I have a flex container with two flex items. I want to set a margin-top on the second one, but only when it's wrapped and not at the first flex line.

If possible, I want to avoid using media queries.

I thought margin-bottom on the first element could be a solution. However, it adds space at the bottom when the elements are not wrapped, so same problem.

This is my code:

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}
.item-big {
  background: blue;
  width: 300px;
}
.item-small {
  background: red;
  margin-top: 30px;
}

<div class="container">
  <div class="item-big">
    FIRST BIG ELEM
  </div>
  <div class="item-small">
    SECOND SMALL ELEM
  </div>
</div>

Css Solutions


Solution 1 - Css

You can add some margin-top to both flex items, and a negative margin-top of the same amount to the flex container.

This way, the negative margin of the flex container will neutralize the margin of the flex items at the first line, but not the margin of the items that wrapped to other lines.

.container {
  margin-top: -30px;
}
.item-big, .item-small {
  margin-top: 30px;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  margin-top: -30px;
}
.item-big, .item-small {
  margin-top: 30px;
  background: red;
}
.item-big {
  background: blue;
  width: 300px;
}

<div class="container">
   <div class="item-big">
      FIRST BIG ELEM
   </div>
   <div class="item-small">
      SECOND SMALL ELEM
   </div>
</div>

Solution 2 - Css

If your browser supports the CSS gap property you can use it like this

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  gap: 20px;
}

gap adds an extra space surrounding the flex-child items. If you want to add some extra space only at the top and bottom, use row-gap instead.

For browsers that not supports the gap property you can use the lobotomized owl selector which selects every element which has an adjacent item right before it, this means it won't select the first one.

.container > * + * {
  margin-top: 20px;
}

If you want to add this marign using * + * operator only if the elements are stacked on top of each other, you should wrap it in @media.

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
QuestionManuel Di IorioView Question on Stackoverflow
Solution 1 - CssOriolView Answer on Stackoverflow
Solution 2 - CssMikolajView Answer on Stackoverflow