11

I would like a flex-direction: column; flexbox container whose width grows to fit the containing elements.

In this codepen:

Screenshot of codepen

The grey div is the flexbox container, and the red divs are contained inside and layed out in columns with flexbox. The grey div needs to expand/contract its width to perfectly contain the red children divs. Is this possible?

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  max-height: 290px;
  align-content: flex-start;
  padding: 2px;
  background: grey;
}
.child {
  background: red;
  width: 100px;
  height: 100px;
  margin: 2px;
}
<div class="container">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Justin McCandless
  • 621
  • 1
  • 10
  • 20

2 Answers2

-1

You didn't set a width behavior of parent element. Set .container display property to inline-block and for each .row element add display: flex property.

.container {
  display: inline-block;
  max-height: 290px;
  padding: 2px;
  background: grey;
}
.row{
  display:flex;
}
.child {
  background: red;
  width: 100px;
  height: 100px;
  margin: 2px;
}
<div class="container">
  <div class="row">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
  </div>
  <div class="row">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
  </div>
</div>
Tomas Chudjak
  • 562
  • 3
  • 11
  • 1
    Looks good, but in my case I'm looking for something that allows me to keep the given html structure. That way you could output the children as you iterate over a list for example, with no other processing to do. – Justin McCandless Mar 24 '15 at 07:53
-1

"Solution"

I use the term solution lightly as this is insanely difficult to do without fixed rows like Tomas suggested (i.e. without altering the HTML to a more conventional style), or generally without some high degree of hacking. Furthermore, the height halves unless there are 2 rows completed and the containing div cannot be reduced in size reliably; comment out child 7 and see what happens. Then when you also uncomment 8 see that it goes back to 'normal'.

I have been messing around for an hour or so and the best I can come up with is in this fiddle.


I'd like to offer a little background

The default flex-flow is row nowrap, this sets a certain width x on the element lucky enough to receive that rule. It appears that in this case changing the flex-flow to column does not reset the width x defined on that element. The element takes the width x as if it were flex-flow: row nowrap (try this for yourself).

There's a whole heap of width inheritance issues that stem from this, we cannot set the flex-basis property (it's not meant to behave like this I believe) so we need to wrap everything in another element .container which we can define width on, and put the actual column styles on a .row element instead. However, .container will not shrink either. At best we have our column properly defined in width with the .container(ing) element for both doing it's own thing.

Thus we require a pseudo element ::after to provide the background with correct width, including some margin and calc() hacks to simulate padding.

I could type a lot more but I don't think this is a viable solution at all, really just a 'proof' of how it cannot be done nicely.

If you wanted to add more rows you'd have to change the width from 50% for 2 (1/2), to 33% for 3 (1/3) etc... it's not really as scaleable as editing the HTML itself.

So to conclude, there's a working demo for 2 rows only but for now this doesn't seem plausible with that current HTML markup structure.

tsujp
  • 1,066
  • 1
  • 12
  • 29
  • Thanks, I was pulling my hair out over this too. At least this shows it's pretty much impossible, so I guess that's the answer right now. – Justin McCandless Mar 24 '15 at 07:57