Home > Mobile >  How to add a “line break” to flexbox, without causing a double-sized gap?
How to add a “line break” to flexbox, without causing a double-sized gap?

Time:05-28

I have a flexbox that uses gap for spacing, which needs to support “line breaks” that cause subsequent flex items to jump down to the next row.

All examples I’ve seen suggest doing this with a new flex item that has flex-basis: 100% (see example below), however that will cause a double-sized gap between the rows, unlike other rows caused by normal item wrapping.

An demonstration of two flexbox rows, each with three items. The rows have twice the gap between them as the columns.

Example:

<div >
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
</div>
.flex {
  display: flex;
  flex-flow: row wrap;
  gap: 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 5px;
}

.break {
  flex-basis: 100%;
}

I’ve tried adding negative top/bottom margins to the line break item, however that doesn’t have any effect for some reason.

Is there a way to add a line break with the same size gap as other lines?

(Swapping gap for margins on the individual items is not an option in this case.)

CodePudding user response:

The gap property is shorthand for row-gap and column-gap. This means that you can provide two values for gap, thus equalizing row and column distance:

gap: 5px 10px;  

.flex {
  display: flex;
  flex-flow: row wrap;
  gap: 5px 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 5px;
}

.break {
  flex-basis: 100%;
}
<div >
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

Using gap: 10px; sets 10px of gap both vertically and horizontally. You can use gap: 5px 10px; for 5px of vertical gap and 10px of horizontal.

.flex {
  display: flex;
  flex-flow: row wrap;
  gap: 5px 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 5px;
}

.break {
  flex-basis: 100%;
}
<div >
  <div ></div>
  <div ></div>
  <div ></div>
  <span ></span>
  <div ></div>
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

Appears this just can’t be done currently using gap, so you have to establish the gap using bottom margins on the flex items instead.

.flex {
  display: flex;
  flex-flow: row wrap;
  column-gap: 10px;
  margin-bottom: -10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 5px;
  margin-bottom: 10px;
}

.break {
  flex-basis: 100%;
}

CodePudding user response:

The best approach I can find for this is to use gap only for gaps in the flow direction (horizontal in this case), and use vertical margin to control vertical spacing.

This feels clunkier than using gap, but by adding negative margin on the flex container (to compensate for the margin on the items) achieves the desired effect without side effects (eg. undesired spacing at the top and bottom):

.flex {
  display: flex;
  flex-flow: row wrap;
  gap: 0 10px;    /* Only use gap for horizontal spacing */
  margin: -5px 0; /* Compensate for item margin */
}

.item {
  width: 100px;
  height: 100px;
  background-color: orange;
  border-radius: 5px;
  margin: 5px 0; /* Add (0.5 * gap) vertical margin to flex items */
}

As a side note, I'm surprised that negative margin on the .break element doesn't work: I'd expect you could solve this by adding margin-top: -10px to it, but that doesn't seem to work.

Edit: Sorry, I missed that last line that "Swapping gap for margins on the individual items is not an option in this case" I'll leave this up just in case the additional step of adding negative margin to the container to compensate for the item margin makes this approach feasible though.

  • Related