1

I trying to figure out if this is possible.

Supposing I've a layout like this:

.flex-container {
  align-content: space-between;
  align-items: flex-start;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.flex-item {
  background: tomato;
  width: 31%;
  height: 150px;
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}
<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
</div>

.flex-container height must be auto, because items are loaded dynamically

  1. How can I accomplish that space-between flex-item in the cross-axis be the same that main-axis (if width of flex-item is 31%, 31x3 = 93% so space-between would be 3.5%).
  2. Change the last flex-item alignment to be like flex-start to avoid the white space between.

Actual layout

Desire layout

Brian
  • 3,850
  • 3
  • 21
  • 37
Mauricio
  • 19
  • 1
  • 3

2 Answers2

2

If you know the amount of space between the elements in advance, then you can apply the margin to all the flexbox items except the first three:

.flex-item:nth-of-type(1n + 4) {
  margin-top: 3.5vw;
}

or:

.flex-item:not(:nth-of-type(-1n + 3)) {
  margin-top: 3.5vw;
}

For the second issue, you can add empty placeholder flexbox items with a height of 0. In doing so, the layout will be calculated taking those elements into account.

Updated Example

.flex-item:empty {
    visibility: hidden;
    height: 0;
    margin: 0;
}

.flex-container {
  align-content: space-between;
  align-items: flex-start;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.flex-item {
  background: tomato;
  width: 31%;
  height: 150px;
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}
.flex-item:not(:nth-of-type(-1n + 3)) {
  margin-top: 3.5vw;
}
.flex-item:empty {
  visibility: hidden;
  height: 0;
  margin: 0;
}
<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
</div>

As Shaggy points out in the comments, you could also set the parent element to justify-content: flex-start and then manually add spacing between the elements:

Updated Example

.flex-container {
  justify-content: flex-start;
}
.flex-item:not(:nth-of-type(-1n + 3)) {
  margin-top: 3.2vw;
}
.flex-item:not(:nth-of-type(3n + 3)) {
  margin-right: 3.2vw;
}
Community
  • 1
  • 1
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • As you're using `margin` to manually set the spacing between each item, you can solve the second issue simply by setting the `justify-content` property of the parent to `flex-start`. – Shaggy Nov 27 '15 at 16:03
  • Thanks @Josh Crozier and Shaggy, whats does "vw" means? Why it works with "vw" and not with "%"? It has the same property of "%"? I didn't know that.... – Mauricio Nov 27 '15 at 17:33
  • The `vw` unit is a viewport-relative percentage. `100vw` is 100% of the width of the viewport and `100vh` is 100% of the height of the viewport. – Josh Crozier Nov 27 '15 at 17:36
  • With `%` margins don't work as expected @JoshCrozier – Mauricio Nov 27 '15 at 17:39
  • @Shaggy Thanks for your comment but I've noticed you use `3.2vw` but the real space between should be `3.5vw`, using `3.5vw` breaks the layout... – Mauricio Nov 27 '15 at 17:52
  • 2
    @Mauricio, use [`calc`](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) to set the width of the children with more accuracy, e.g. `width:calc(33.333% - 3.5vw)`, or, for even more accuracy, `width:calc((100% / 3) - 3.5vw)`. – Shaggy Nov 27 '15 at 18:01
  • @Shaggy Supposing I want to use `50% widht' in `.flex-container`, then using `vw margin` will break the layout in this case, is there another way to use margins top/bottom relative to the container with flexbox – Mauricio Nov 27 '15 at 20:11
  • Then just adjust the margins accordingly. In that instance, they'd become `1.75vw`. – Shaggy Nov 27 '15 at 20:27
1

You can use row-gap property to set the gaps between the flex items. .flex-item { row-gap: 3.5vw; }

Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container#creating_gaps_between_items