margin-top only when the flex item is wrapped

45.6k views Asked by At

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>

3

There are 3 answers

4
Oriol On BEST ANSWER

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>

Nowadays there is overall support (MDN) for the css (row-)gap property in flex layout containers which this answer proposes. The way to go .

0
Artur INTECH On

The column-gap property is also worth mentioning (in addition to what @Mikolaj already answered).

So the full list of the properties involved is as follows:

3
Mikolaj On

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 margin using * + * operator only if the elements are stacked on top of each other, you should wrap it in @media.

The third solution with :not() and :first-child CSS pseudo-class

.container:not(:first-child) {
  margin-top: 20px;
}