Sean Werkema Sean Werkema - 5 months ago 18
CSS Question

Make flexbox wrap rows upside-down

Today I was looking at a 'Tabs' HTML gizmo that I'd built, and I noticed that since I was using inline-block to lay out the tab headers, when they wrapped, I'd get output that looked something like this:


+-------+ +--------+ +--------+ +------+ +------------+ +-----+
| Apple | | Banana | | Cherry | | Date | | Elderberry | | Fig |
+-------+ +----------+
| Grape | | Honeydew |
--+ +--------------------------------------------------------------


No problem, I thought: I bet I can use flexbox to make it wrap more cleanly, so that the second row goes above the first so that it looks like it's "behind" the first row to the user, like this:


+-------+ +----------+
| Grape | | Honeydew |
+-------+ +--------+ +--------+ +------+ +------------+ +-----+
| Apple | | Banana | | Cherry | | Date | | Elderberry | | Fig |
--+ +--------------------------------------------------------------


That's not perfect, but it's not bad, either, and it mimics what the Tab control does in Windows.

So I hacked up a few lines of flex CSS and got to the point where all I'd have to do is add whatever the flexbox property was that specifies rows go from bottom to top, and then I'd be done. I got to this:

ul.fruits {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-end;
align-content: flex-end;
}




The spec, of course, says that the cross-axis matches the writing direction (link to W3C spec). And then I realized that I couldn't add
writing-mode: horizontal-bt
to make it go bottom-to-top because there is no such
writing-mode
in CSS (link to W3C spec).

I realize that there's not a lot of demand for paragraphs that wrap in reverse row order, but this seems like a thing that's occasionally useful, and doesn't seem to exist in the spec.

(Possible hacky solution: I suppose I could use CSS transforms to flip the container and then flip back the elements within it, but that seems like a cop-out for something that should "just work.")

So does anybody have any good ideas on how you might get flexbox to wrap rows such that the cross-axis goes in the opposite direction of that specified in the writing-mode? Is it even possible?




( JSFiddle example to play with can be found here: https://jsfiddle.net/seanofw/Lk9wyL9s/ )

Answer

Try:

flex-flow: row wrap-reverse

Revised Fiddle

5.2. Flex Line Wrapping: the flex-wrap property

The flex-wrap property controls whether the flex container is single-line or multi-line, and the direction of the cross-axis, which determines the direction new lines are stacked in.

nowrap

The flex container is single-line.

wrap

The flex container is multi-line.

wrap-reverse

Same as wrap.

For the values that are not wrap-reverse, the cross-start direction is equivalent to either the inline-start or block-start direction of the current writing mode (whichever is in the cross axis) and the cross-end direction is the opposite direction of cross-start.

When flex-wrap is wrap-reverse, the cross-start and cross-end directions are swapped.

(emphasis added)

Related, but likely not useful in this case, are flex-direction values: