Search code examples
cssflexboxnestedword-wrap

Nested column flexbox inside row flexbox with wrapping


I have a page with nested flex boxes here: http://jsfiddle.net/fr0/6dqLh30d/

<div class="flex-group">
  <ul class="flex-container red">
    <li class="flex-item">1</li>
    <li class="flex-item">2</li>
    <li class="flex-item">3</li>
  </ul>

  <ul class="flex-container gold">
    <li class="flex-item">1</li>
    <li class="flex-item">2</li>
    <li class="flex-item">3</li>
    <li class="flex-item">4</li>
    <li class="flex-item">5</li>
  </ul>

  <ul class="flex-container blue">
    <li class="flex-item">1</li>
    <li class="flex-item">2</li>
    <li class="flex-item">3</li>
    <li class="flex-item">4</li>
    <li class="flex-item">5</li>
    <li class="flex-item">6</li>
    <li class="flex-item">7</li>
    <li class="flex-item">8</li>
  </ul>
<div>

And the (relevant) CSS:

 .flex-group {
   display: flex;
   flex-direction: row;
   height: 500px;
 }

 .flex-container {
   padding: 0;
   margin: 0;
   list-style: none;
   border: 1px solid silver;
   display: flex;
   flex-direction: column;
   flex-wrap: wrap;
   flex: 0 0 auto;
 }

 .flex-item {
   padding: 5px;
   width: 100px;
   height: 100px;
   margin: 10px;

   line-height: 100px;
   color: white;
   font-weight: bold;
   font-size: 2em;
   text-align: center;
 }

The outer flexbox (.flex-group) is meant to lay out from left-to-right. The inner flexboxes (.flex-container) are meant to layout from top-to-bottom, and should wrap if there isn't enough space (which there isn't in my jsfiddle). What I want to happen, is that the .flex-containers will grow in the X direction when the wrapping happens. But that's not occurring. Instead, the containers are overflowing.

What I want it to look like (in Chrome): https://dl.dropboxusercontent.com/u/57880242/flex-good.png

Is there a way to get the .flex-containers to size appropriately in the X direction? I don't want to hard-code their widths, since the items that appear in these lists will be dynamic.


Solution

  • I've been playing with this for a few minutes now, and I think I've got what you're looking for.

    Here's the CSS

    .flex-group {
        margin: auto;
        display: flex;
        flex-direction: row;
        justify-content: space-around;
    }
    
    .flex-container {
        flex: 0 1 auto;
    
        display: flex;
        flex-flow: row wrap;
        align-items: space-around;
        align-content: flex-start;
    
        padding: 0;
        margin: 0;
        list-style: none;
        border: 1px solid silver;
    }
    
    .red li {
        background: red;
    }
    
    .gold li {
        background: gold;
    }
    
    .blue li {
        background: deepskyblue;
    }
    
    .flex-item {
        flex: 0 1 auto;
    
        padding: 5px;
        width: 100px;
        height: 100px;
        margin: 10px;
    
        line-height: 100px;
        color: white;
        font-weight: bold;
        font-size: 2em;
        text-align: center;
    }
    

    And here's an updated fiddle to see it in action.