Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use css3 flexbox to create multi-column layout without expanding vertically?

I'm playing with css3's flexbox in Chrome (no need to worry about cross-browser for this). I'm having a hard time convincing it to lay out my content the way I'd like. Here's a sketch of my goal:

enter image description here

Here's a jsFiddle of my attempt: http://jsfiddle.net/Yht4V/2/ This seems to work great except each .group will expand its height rather than create multiple columns.

I'm using flexbox pervasively here. The body lays out vertically, with the #content div taking the remaining height of the page. Each .group is laid out horizontally. Finally, each .item is laid out within a .group vertically with wrapping.

Unfortunately, each .group ends up as a single column by expanding the #content height, which causes a vertical scrollbar (unwanted). If I set the height of each .group to a fixed pixel size, the items break out into multiple columns, but this defeats the fluidity of the flexbox. Here's what it looks like with fixed heights: http://jsfiddle.net/Yht4V/3/

So, how can I get my #content div to not expand vertically since everything is managed with flexboxes without setting a fixed height? I was expecting the flexbox to trigger more columns instead of expanding the height of its parent and causing a scrollbar.

like image 599
Bret Kuhns Avatar asked Dec 27 '12 17:12

Bret Kuhns


People also ask

How do I create a two column layout using flexbox?

Approach: To create a two-column layout, first we create a <div> element with property display: flex, it makes that a div flexbox and then add flex-direction: row, to make the layout column-wise. Then add the required div inside the above div with require width and they all will come as columns.

How do you equally divide flex into two columns?

Use a container with display: flex and assign the width to 50% to the two parts you want to divide.


1 Answers

From what I've seen with the Chrome and Opera implementations for Flexbox, a flex-direction of column requires restricting the height of the element, otherwise it will continue expanding vertically. It doesn't have to be a fixed value, it can be a percentage.

That said, the layout you want for your .group elements can also be achieved by using the CSS Columns module. The flow of the elements will be similar to that of the flexbox column orientation, but it will create columns as long as there's enough width for them, regardless of how long the document is.

http://jsfiddle.net/Yht4V/8/ (you'll have to excuse the lack of prefixes)

html {
    height: 100%;
}

body {
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
}

h1 {
    padding: 1em;
}

#content {
    padding: 10px;
    background-color: #eee;
    display: flex;
    flex-grow: 1;
}

#content > .group {
    margin: 10px;
    padding: 10px;
    border: 1px solid #cfcfcf;
    background-color: #ddd;
    flex: 1 1 auto;
}

#content > .group:first-child {
    columns: 10em;
    flex-grow: 2;    
}

#content > .group .item {
    margin: 10px;
    padding: 10px;
    background-color: #aaa;
    break-inside: avoid;
}

#content > .group .item:first-child {
    margin-top: 0;
}

Leaving it as a bunch of nested flexboxes, this was about as close as I could get it:

http://jsfiddle.net/Yht4V/9/ (again, no prefixes)

html {
    height: 100%;
}

body {
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
}

h1 {
    padding: 1em;
}

#content {
    padding: 10px;
    background-color: #eee;
    display: flex;
    flex: 1 1 auto;
    height: 100%;
    width: 100%;
}

#content > .group {
    margin: 10px;
    padding: 10px;
    border: 1px solid #cfcfcf;
    background-color: #ddd;

    display: flex;
    flex-flow: column wrap;
    flex: 1 1 30%;
    max-height: 100%;
}

#content > .group .item {
    margin: 10px;
    padding: 10px;
    background-color: #aaa;
}
like image 159
cimmanon Avatar answered Oct 09 '22 02:10

cimmanon