2

I want a grid to wrap when constrained by an outer node:

So the following should have two cells one on top of each other, but it renders them side by side:

<div style="display:flex; width:100px">
    <div style="flex: 1; width: 100px;">foo</div>
    <div style="flex: 1; width: 100px;">bar</div>
</div>

How can I achieve my desired result?

Ben Aston
  • 53,718
  • 65
  • 205
  • 331

4 Answers4

4

Just add flex-wrap: wrap; (the second example below wraps, the first one not since the container's width is wide enough to accomodate both children in one line)

<div style="display:flex; flex-wrap: wrap; width:200px; margin-bottom: 50px; border: 1px solid blue;">
    <div style="width: 100px;">foo</div>
    <div style="width: 100px;">bar</div>
</div>

<div style="display:flex; flex-wrap: wrap; width:100px; border: 1px solid red;">
    <div style="width: 100px;">foo</div>
    <div style="width: 100px;">bar</div>
</div>
Johannes
  • 64,305
  • 18
  • 73
  • 130
2

Organize them in column direction:

.container {
display: flex;
justify-content: left;
align-items: center;
}
.row > div {
width: 50px;
height: 50px;
background-color: lightgray;
}
<div class="container">
  <div class="row">
    <div>foo</div>
    <div>bar</div>
  </div>
  <div class="row">
    <div>foo</div>
    <div>bar</div>
  </div>
</div>
Gerard
  • 15,418
  • 5
  • 30
  • 52
  • Can you describe for me what specifying the flex direction is actually doing? – Ben Aston Jun 08 '17 at 13:00
  • 1
    This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept. Think of flex items as primarily laying out either in horizontal rows or vertical columns. – Gerard Jun 08 '17 at 13:01
  • If I have four cells, each of 50px width, will this form a square grid? – Ben Aston Jun 08 '17 at 13:04
  • No, it will create a single column. – ajm Jun 08 '17 at 13:04
  • OK, I would like a wrapped grid – Ben Aston Jun 08 '17 at 13:07
  • `flex-wrap` should do the trick for you. A few other answers mention it. The trick is that your initial example would work with either method. It's when the widths change and you want to form a grid that `flex-wrap` becomes preferred. – ajm Jun 08 '17 at 13:10
  • Code is adjusted. A little styling for visualization. – Gerard Jun 08 '17 at 13:14
2

Setting the parent to flex-wrap will allow it to wrap, while using flex:0 1 auto, show for flex: [flex-grow] [flex-shrink] [flex-basis], will stop the child from shrinking onto one row. This is also the default for flex children.

<div style="display:flex; width:100px; flex-wrap:wrap;">
    <div style="flex:0 1 auto; width: 100px;">foo</div>
    <div style="flex:0 1 auto; width: 100px;">bar</div>
</div>

<div style="display:flex; width:100px; flex-wrap:wrap;">
    <div style="flex:0 1 auto; width: 50px;">foo</div>
    <div style="flex:0 1 auto; width: 50px;">bar</div>
    <div style="flex:0 1 auto; width: 50px;">foo</div>
    <div style="flex:0 1 auto; width: 50px;">bar</div>    
</div>
Benneb10
  • 1,419
  • 1
  • 8
  • 13
1

You have two possibilities.

You can set flex-direction to column. This will set a vertical main-axis, laying out your items vertically.

You can also set flex-wrap to wrap. This tells your flex container that it's OK to wrap elements when they would exceed their parent's width. In your case, it would wrap your second element to the next "row."

If your items are the same width as their parent container as in your example, both methods will work the same way. If the items have a different width than their parent (or, really, in any other case where you'll want elements side-by-side in a grid like the case you mention in your comment), you'll want to use flex-wrap so things layout correctly side-by-side before wrapping to another row.

ajm
  • 19,795
  • 3
  • 32
  • 37