ixM
ixM

Reputation: 1264

Can you make a nested column flexbox as small but as wide as possible

In the code snippet below, I have two flexbox containers: A primary one, wrapped row, and a second one, nested in the first one, that has a column direction.

I'd like to have the red, green & blue containers displayed like this:

--------------
red   | black
--------------
green | gray
--------------
blue  | 
--------------

instead of simply stacked like this:

--------
red
--------
green
--------
blue
--------
black
--------
gray
--------

Is this a possible behaviour? Thanks!

.flexbox {
  display: flex;
  flex-wrap: wrap;
}

.flexbox-element {
  flex: 1 1 auto;
}

.flexbox-column {
  flex-direction: column;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}

.green {
  background-color: green;
}

.yellow {
  background-color: yellow;
}

.orange {
  background-color: orange;
}

.violet {
  background-color: violet;
}

.black {
  background-color: black;
}

.gray {
  background-color: gray;
}

.flexbox-element {
  width: 200px;
  min-height: 200px;
}
<div class="flexbox" style="flex: 1; width: 500px">
  <div class="flexbox flexbox-element flexbox-column" style="flex: 1 1 100%">
    <div class="flexbox-element red"></div>
    <div class="flexbox-element green"></div>
    <div class="flexbox-element blue"></div>
    <div class="flexbox-element black"></div>
    <div class="flexbox-element gray"></div>
  </div>
  <div class="flexbox-element yellow"></div>
  <div class="flexbox-element orange"></div>
  <div class="flexbox-element violet"></div>
</div>

Upvotes: 3

Views: 330

Answers (2)

FelipeAls
FelipeAls

Reputation: 22171

  1. CSS3 Multicolumns solution
  2. CSS3 Grid layout solution

Due to the limitations of Flexbox when direction is column (you need to limit the height somehow or else it won't wrap in a second column), it's a simpler job for CSS3 Multicolumns:

.col-2 {
  columns: 2;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
}

.flexbox-element {
  flex: 1 1 auto;
}

.col-2 {
  columns: 2;
  width: 100%;
  outline: 1px dashed blue;
}

.col-2 > * {
  width: 50%;
  min-height: 200px;
  outline: 1px dotted red;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}

.green {
  background-color: green;
}

.yellow {
  background-color: yellow;
}

.orange {
  background-color: orange;
}

.violet {
  background-color: violet;
}

.black {
  background-color: black;
}

.gray {
  background-color: gray;
}

.flexbox-element {
  width: 200px;
  min-height: 200px;
}
<div class="flexbox" style="flex: 1; width: 500px">
  <div class="flexbox flexbox-element col-2" style="flex: 1 1 100%">
    <div class="red">A</div>
    <div class="green">B</div>
    <div class="blue">C</div>
    <div class="black">D</div>
    <div class="gray">E</div>
  </div>
  <div class="flexbox-element yellow"></div>
  <div class="flexbox-element orange"></div>
  <div class="flexbox-element violet"></div>
</div>


You could also use CSS3 Grid layout but you'll need to position manually each grid item in IE10-11 and Edge 12-15 (current Edge 16 supports the same newer recommendation that other modern browsers)

Grid layout (compat Edge 16+ and other modern browsers. IE11 needs explicit positioning of both row and column of each grid item)

➡️ https://codepen.io/PhilippeVay/pen/GdBpJa?editors=0100

.col-2 {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: repeat(2, minmax(0, 1fr)); /* 2 columns with strict equal width */
}

.col-2 > :nth-child(odd) {
  grid-column: 1; /* even items can now only occupy the 2nd column */
}

Upvotes: 1

soywod
soywod

Reputation: 4520

If you remove the flex-direction: column and the flex: 1 to the first group, you should get what you want.

.flexbox {
  display: flex;
  flex-wrap: wrap;
}

.flexbox-column {
  flex-direction: column;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}

.black {
  background-color: black;
}

.gray {
  background-color: gray;
}

.green {
  background-color: green;
}

.yellow {
  background-color: yellow;
}

.orange {
  background-color: orange;
}

.violet {
  background-color: violet;
}

.flexbox-element {
  width: 200px;
  min-height: 200px;
}

.flexbox-group {
  width: 400px;
  height: 600px;
  flex-direction: column;
}
<div class="flexbox" style="flex: 1; width: 500px">
  <div class="flexbox flexbox-element flexbox-group">
    <div class="flexbox-element red"></div>
    <div class="flexbox-element green"></div>
    <div class="flexbox-element blue"></div>
    <div class="flexbox-element black"></div>
    <div class="flexbox-element gray"></div>
  </div>
  <div class="flexbox-element yellow"></div>
  <div class="flexbox-element orange"></div>
  <div class="flexbox-element violet"></div>
</div>

Upvotes: 2

Related Questions