margin-top only when the flex item is wrapped
Asked Answered
R

3

147

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>
Ratcliffe answered 17/6, 2015 at 9:7 Comment(4)
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Please don't abuse the code blocks to get around this requirement.Herb
The problem is that in this case I didn't need to explain with more code, so it's a problem of StackOverflow if a block code is required.Ratcliffe
The issue is the usefulness for future users of SO. If your JSfiddle link went away then your post is essentially useless. That's why SO asks for code....ideally in the code snippets available to you when you create the question.Herb
Ok, I understood, I'm editing the question to comply the rules ;)Ratcliffe
J
266

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 🙌🏼.

Juvenilia answered 17/6, 2015 at 12:40 Comment(4)
Oh CSS, why u do dis to meMinnesinger
This doesn't work when the container has a background color or borderRosana
@FrankvanWijk Use a nested transparent div for your margin-fix, and the parent for the visual elements.Dissemble
For others in 2021 and beyond, looking for a less hacky answer, checkout the CSS 'gap' property: coryrylan.com/blog/css-gap-space-with-flexboxPica
C
26

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;
}
Culture answered 10/11, 2021 at 10:20 Comment(3)
Good feature, but still poorly supported in Safari (only latest versions will work). So if you want to support a-bit-older browsers then prefer to use mix of negative/positive margins to create gaps.Cheery
Also second solution for older browsers will not help: second column is counted as second element and top margin will be added.Cheery
Works well in Safari nowIneligible
C
1

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:

Cautionary answered 30/11, 2023 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.