10

Edit Unlike The difference between flex:1 and flex-grow:1 . While the answer ultimately was the use of flex instead of flex-grow, my question was not the difference between the two but rather how to get nested flex-boxes to wrap appropriately. For someone struggling with this issue, there would be no way to find that answer on SO without already knowing the issue was the use of flex vs. flex-grow. If I already knew the issue was the difference between flex and flex-grow, I wouldn't have needed to ask the question.

Edit 2 If this post is going to be flagged as duplicate, it would be better to list it as a duplicate of Nested column flexbox inside row flexbox with wrapping instead of The difference between flex:1 and flex-grow:1.

I have a series of div tags that are defined as display:flex. They are laid out as a row with 3 columns. The first two columns are given a width and the third column is allowed to stretch to fill the rest of the space. The row is also set to wrap so that on smaller screens, the third column will wrap below the other two columns.

Here is some basic example code:

style.css

.flex-row {
    display: flex;
    flex-direction: row;
    flex-grow: 1;
}

.flex-column {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    border: 1px solid lightgray;
}

.box {
    display: flex;
    height: 100px;
    width: 300px;
    min-width: 200px;
    flex-shrink: 1;
    border: 1px solid green;
}

index.html

<div class="flex-row" style="flex-wrap:wrap">
  <div class="flex-column" style="flex-grow:0">
      Column 1
  </div>

  <div class="flex-column" style="flex-grow:0;width:200px">
    Column 2
  </div>

  <div class="flex-column">
    <div class="flex-row" style="min-width:500px;flex-wrap:wrap">
      <div class="box">Box 1</div>
      <div class="box">Box 2</div>
      <div class="box">Box 3</div>
      <div class="box">Box 4</div>
      <div class="box">Box 5</div>
      <div class="box">Box 6</div>
      <div class="box">Box 7</div>
    </div>
  </div>
</div>

(see my plnk here).

The last column contains a flex row with a series of "boxes" (see the example).

The desired effect is that as the screen is resized, the third column will continue to shrink down to the point where all the boxes are in a single column and the boxes have shrunk to their min-width. At that point, any further reduction in the screen width would cause the third column to wrap below the other two columns and it would then again expand to include as many boxes side by side as possible.

What seems to be happening in practice is that the third column wraps first -- before wrapping the contents it contains.

Here is a visual picture of what I'm want to see happen.

Here is a visual picture of what I'm trying to accomplish.

Is this possible to do with flexbox? If so, what am I doing wrong?

RHarris
  • 10,641
  • 13
  • 59
  • 103
  • Furthermore, why the given answer work is because it sets the 3rd column's _flex-basis_ to 0, hence the contents width is not taken into account, which leads to, when that 3rd column reach its _min-width_, it wraps. If you resize the code sample enough, you'll see the boxes will overflow the column before it wraps. A proper solution would need a media query to accomplish this, as the normal wrap order starts with the outer most children and work inwards. – Asons Dec 06 '17 at 20:06
  • I concede that while the accepted answer did provide the result I was looking for, it provides misleading information in regards to how flex works. However, I do think the solution I pointed to in my Edit 2 is closer to being a duplicate of my question as opposed to the one proposed by Michael_B. – RHarris Dec 06 '17 at 20:39
  • Feel free to refer it yourself : https://css-tricks.com/snippets/css/a-guide-to-flexbox/ –  Dec 06 '17 at 20:43
  • I have added that link to the dupe list, so now both are covered. I still find it very misleading having such answer accepted since its explanation is wrong. Hopefully the dupe links will help users find the right way how it works. – Asons Dec 06 '17 at 20:43

1 Answers1

5

Here is what you desire. What you need to change :

  • For the flex-column it should be flex: 1; instead of flex-grow:1; and set a min-width to it. This way, it can grow and shrink both.

Using flex-grow:1 limits the container to only grow but not shrink and since you're using the flex-column class in the initial container i.e flex-row you need it to be flexible as the viewport is resized.

/* Styles go here */

.flex-row {
  display: flex;
  flex-direction: flex-row;
  flex-grow: 1;
}

.flex-column {
  display: flex;
  flex-direction: column;
  min-width:100px;
  flex: 1;
  border: 1px solid lightgray;
}

.box {
  display:flex;
  flex-shrink:1;
  border: 1px solid green;
  height:100px;
  width:300px;
  min-width:150px;
}
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

  <body>
    <div class="flex-row" style="flex-wrap:wrap">
      <div class="flex-column" style="flex-grow:0">
          Column 1
      </div>
      
      <div class="flex-column" style="flex-grow:0;width:200px">
        Column 2
      </div>
      
      <div class="flex-column">
        <div class="flex-row" style="min-width:500px;flex-wrap:wrap">
          <div class="box">Box 1</div>
          <div class="box">Box 2</div>
          <div class="box">Box 3</div>
          <div class="box">Box 4</div>
          <div class="box">Box 5</div>
          <div class="box">Box 6</div>
          <div class="box">Box 7</div>
        </div>
      </div>
    </div>
  </body>

</html>
  • 1
    Perfect! Thanks. That was way too easy -- can't believe I missed that. – RHarris Dec 06 '17 at 15:21
  • @RHarris No problem :) –  Dec 06 '17 at 15:21
  • When you say _"Using `flex-grow:1` limits the container to only grow but not shrink"_ it is as wrong as it can get, and you obviously doesn't understand their difference. Maybe you should have a look here: https://stackoverflow.com/questions/45767405/the-difference-between-flex1-and-flex-grow1 – Asons Dec 06 '17 at 18:41
  • @LGSon "flex-shrink: This defines the ability for a flex item to shrink if necessary." "flex-grow: This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up. " And if you did "flex-basis:This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword." If you did look at the code and what I meant by that, you'd understand why the column weren't "shrinking" . –  Dec 06 '17 at 20:37
  • @LGSon In before it was marked as duplicate either, by you or anyone else. It would have been a duplicate if the asker had the idea of what was going wrong with his code particularly with "flex-grow:1". He wasn't "confused" about flex or flex-grow. Its saying as if, any two questions regarding a particular thing makes them duplicate. –  Dec 06 '17 at 20:38