CSS flex-basis not working when flex-direction is 'column'

css, flexbox, html

Solution

Why it doesn't work:

Flex wrap only happens when the initial main size of the flex items overflows the flex container. In the case of `flex-direction: row`, this is when they flex items are wider than the container. With `flex-direction: column`, they must overflow the height of the container.

But in CSS, height behaves fundamentally differently than width. The height of a container in CSS is determined by the height of its children. Thus, without something constraining the container’s height, they flex items will never overflow; they just make their container taller. If they don’t overflow, they won’t wrap.

Possible solutions:

You have to constrain the height of the container. The obvious way (which you said is off the table), is setting an explicit `height` or `max-height`.

Ask yourself why you need to constrain the height. Is it to stay within the viewport? You could use viewport-relative units and set something like `max-height: 100vh`. Is it to equal the height of another column outside this flex container? You might be able to constrain it with another flexbox. Make this flex container a flex item in an outer flexbox. Something else in that outer flexbox would have to establish its height, though.

Problem

My goal is to create a two-column layout with flexbox wherein the first column has two rows and the second column has one, like this: Setting `flex-basis: 100%` on the third item gives the desired effect, but only when the container's `flex-direction` is `row`: Changing `flex-direction` to `column` results in the following, unless the `height` is set explicitly, which is infeasible in my project: How can I get the first image without explicitly setting the `height` of the container? Here's a Plunker illustrating the problem. ``` body { display: flex; height: 100px; width: 100px; } .container { display: flex; flex-direction: column; /* Setting this to `row` gives the expected effect,but rotated */ flex-grow: 1; flex-wrap: wrap; /* height: 100%; */ /* Setting this fixes the problem, but is infeasible for my project*/ } .item { flex-grow: 1; } .one { background-color: red; } .two { background-color: blue; } .three { background-color: green; flex-basis: 100%; } ``` ``` <div class="container"> <div class="item one">&nbsp;</div> <div class="item two">&nbsp;</div> <div class="item three">&nbsp;</div> </div> ```

Original source