1

I have two .flex-container with 3 .box children that I want to set up differently. See my snippet for a visual and my solution.

The first is easy as I can set the first box to be width: 100%; and then just use flex-wrap: wrap;. Good to go.

For the second .flex-container I found I had to add an extra container .box-container around the last two boxes and then give it flex: auto; to get the desired effect.

My question is do I need this extra container .box-container? If the answer is yes, so be it. I feel like I am missing something fundamental, but I'm thinking it could require it because these layouts aren't height-based and I guess it's vertically oriented? I tried using flex-direction: column; in different ways.

Any solution using flexbox and no extra containers, like the first layout I presented, would be much appreciated. Thank you.

* {
  box-sizing: border-box;
}

section {
  display: flex;
  margin-bottom: 10px;
  padding: 10px;
  border-radius: 5px;
}

.flex-container-1 {
  flex-wrap: wrap;
  border: 3px solid seagreen;
  background-color: mediumseagreen;
}

.flex-container-1 .box:first-of-type {
  width: 100%;
}

.flex-container-2 {
  border: 3px solid firebrick;
  background-color: indianred;
}

.box-container {
  flex: auto;
}

.box {
  display: flex;
  justify-content: center;
  align-items: center;
  flex: auto;
  padding: 10px;
  border: 1px solid #fff;
}

.box .box-num {
  font-size: 40px;
  color: #fff;
}
<section class="flex-container-1">
  <div class="box">
    <span class="box-num">1</span>
  </div>
  <div class="box">
    <span class="box-num">2</span>
  </div>
  <div class="box">
    <span class="box-num">3</span>
  </div>
</section>

<section class="flex-container-2">
  <div class="box">
    <span class="box-num">1</span>
  </div>
  <div class="box-container">
    <div class="box">
      <span class="box-num">2</span>
    </div>
    <div class="box">
      <span class="box-num">3</span>
    </div>
  </div>
</section>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
StefanBob
  • 4,857
  • 2
  • 32
  • 38
  • 1
    If you can set a fixed height on the container, then the second example can be achieved using the same method as the first, except with `column wrap`. If not, then you need a nested container for items 2 & 3. – Michael Benjamin Apr 24 '17 at 19:44
  • 1
    If you don't care about IE / Edge support, then CSS Grid Layout can handle this easily. – Michael Benjamin Apr 24 '17 at 19:45
  • Thanks Michael that's the answer I needed. Also +1 I never think to use flex-flow until now. Makes sense – StefanBob Apr 24 '17 at 19:54

2 Answers2

1

Flex Layout

You cannot make flex items wrap under other items in the same row. That's just not how flexbox works, which is along horizontal and vertical lines. So to stack two items next to one in the same "row", you'll need a bit of CSS or HTML trickery.

You can either:

  • Define a height on the container. This will enable you to use flex-flow: column wrap to stack items 2 and 3 next to item 1 as two equal height columns, otherwise...

  • Use a nested container. This will allow you to wrap items 2 and 3 in one item which can become a sibling of item 1, and both columns can have equal height.

These concepts and their limitations are further explained in my answer here:


Grid Layout

Because CSS Grid Layout is now supported by most major browsers, and because your layout objective is simple with this new technology, and because with Grid Layout you'll never need to wrap items in nested containers or set a fixed height on the main container, I've posted an answer below:

article {
  display: grid;                            /* 1 */
  grid-template-columns: repeat(2, 1fr);    /* 2 */
}

section:nth-child(1) {
  grid-row: 1 / 3;                          /* 3 */
}

/* non-essential decorative styles */

article {
  padding: 10px;
  border-radius: 5px;
  border: 3px solid firebrick;
  background-color: indianred;
}
section {
  padding: 10px;
  border: 1px solid #fff;
  font-size: 40px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
* {
  box-sizing: border-box;
}
<article>
    <section>1</section>
    <section>2</section>
    <section>3</section>
</article>

Notes:

  1. Establish block-level grid container. (spec reference)
  2. Instruct the grid to create two equal width columns. 1fr represents a proportion of free space. It's similar to flex-grow: 1. (spec reference)
  3. Instruct the first item to span two rows (i.e., from grid row line 1 to grid row line 3, which covers two grid tracks). (spec reference)

Browser Support for CSS Grid

  • Chrome - full support as of March 8, 2017 (version 57)
  • Firefox - full support as of March 6, 2017 (version 52)
  • Safari - full support as of March 26, 2017 (version 10.1)
  • Edge - full support as of October 16, 2017 (version 16)
  • IE11 - no support for current spec; supports obsolete version

Here's the complete picture: http://caniuse.com/#search=grid

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Yes. Unless I use a fixed height on the container.

StefanBob
  • 4,857
  • 2
  • 32
  • 38