prevent line wrap between certain flex child elements

Viewed 447

I have some elements layout using display: flex like this:

<div style="resize: horizontal; overflow: hidden; border: 10px solid black;">
  <div style="display: flex; flex-wrap: wrap;">
    <div style="flex: 0 0 100px; border: 10px solid #f77;">A</div>
    <div style="flex: 0 0 20px; border: 10px solid #373;">B</div>
    <div style="flex: 0 0 100px; border: 10px solid #f77;">C</div>
    <div style="flex: 0 0 20px; border: 10px solid #373;">D</div>
    <div style="flex: 0 0 100px; border: 10px solid #f77;">E</div>
    <div style="flex: 0 0 20px; border: 10px solid #373;">F</div>
  </div>
</div>

I had used flex-wrap: wrap make line break possible in flex layout context. But I want the wrap only happen between (B, C), (D, E) whenever needed. And avoid any wrap happen between (A, B), (C, D), (E, F).

For example, when the container have 300px width, it should layout as

A B
C D
E F

But not

A B C
D E F

Currently, when container have certain width, wrap between (B, C) or (D, E) are possible. How can I avoid this?

1 Answers

Treat every pair of elements—(A,B), (C,D), (E,F)—as a separate flex item to ensure they wrap into flex lines together. Or use grid layout for a simpler solution.

Flexbox solution

Every time you resize the flex container, the flex container will try to figure out how many flex items can fit into any given line. Each element (A, B, C, etc.) is evaluated separately for this purpose, which means that one element in a pair might fit into a flex line, and the other may wrap into the next line.

To ensure these pairs wrap together, you could wrap each pair into another element. That way your flex container doesn’t see individual elements as flex items anymore (A, B, C, D, and so on). Instead, it will see pairs as flex items (AB, CD, EF). Then each pair element can be a flex container itself to make sure the elements inside are laid out horizontally.

<div style="resize: horizontal; overflow: hidden; border: 10px solid black">
  <div style="display: flex; flex-wrap: wrap">
    <div class="flex-item" style="flex: none; display: flex">
      <div style="width: 100px; border: 10px solid #f77">A</div>
      <div style="width: 20px; border: 10px solid #373">B</div>
    </div>
    <div class="flex-item" style="flex: none; display: flex">
      <div style="width: 100px; border: 10px solid #f77">C</div>
      <div style="width: 20px; border: 10px solid #373">D</div>
    </div>
    <div class="flex-item" style="flex: none; display: flex">
      <div style="width: 100px; border: 10px solid #f77">E</div>
      <div style="width: 20px; border: 10px solid #373">F</div>
    </div>
  </div>
</div>

Grid solution

CSS Grid Layout lets you express more complex layouts without any extra HTML elements. So you could keep your markup, and edit just the styles.

In this case, you want to express that you want as many pairs of elements as possible, and that if a pair can’t fit, it should go into a new row. That way, elements will always go together as these pairs.

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 120px 40px);
  resize: horizontal;
  overflow: hidden;
  border: 10px solid black;
}

.grid-item-big {
  border: 10px solid #f77;
}

.grid-item-small {
  border: 10px solid #373;
}
<div class="grid-container">
  <div class="grid-item-big">A</div>
  <div class="grid-item-small">B</div>
  <div class="grid-item-big">C</div>
  <div class="grid-item-small">D</div>
  <div class="grid-item-big">E</div>
  <div class="grid-item-small">F</div>
</div>

Related