I have a webapp with which I'm using flexbox for layout.
I'm trying to both fill the screen (it's an app, not a document), and as far as possible to not specify any fixed widths or heights as the content could be all sorts of things (Full fluid layout! The dream!)
So I need fluid height, full width headers and footers, and then a main panel in the middle filling the remaining vertical space, divided into columns, each of which scrolls when too high, and where the width of each non-primary column should shrink to fit its content, and a primary column which uses up the remaining space.
I am so close, but have had to resort to explicitly sizing the non-main columns - I believe that flex-basis: content;
is supposed to do this but isn't supported by browsers yet.
Here's a minimal demo showing fixed size columns:
var list = document.querySelector('ul')_x000D_
_x000D_
for (var i = 0; i < 100; i++) {_x000D_
var li = document.createElement('li')_x000D_
li.textContent = i_x000D_
list.appendChild(li)_x000D_
}
_x000D_
html,_x000D_
body {_x000D_
height: 100%;_x000D_
width: 100%;_x000D_
margin: 0;_x000D_
}_x000D_
body {_x000D_
display: flex;_x000D_
flex-direction: column;_x000D_
}_x000D_
main {_x000D_
display: flex;_x000D_
flex-direction: row;_x000D_
overflow: hidden;_x000D_
}_x000D_
main > section {_x000D_
overflow-y: auto;_x000D_
flex-basis: 10em;_x000D_
/* Would be better if it were fluid width/shrink to fit, unsupported: */_x000D_
/* flex-basis: content; */_x000D_
}_x000D_
main > section:last-child {_x000D_
display: flex;_x000D_
flex: auto;_x000D_
flex-direction: column;_x000D_
}_x000D_
main > section:last-child > textarea {_x000D_
flex: auto;_x000D_
}
_x000D_
<header>_x000D_
<h1>Heading</h1>_x000D_
</header>_x000D_
_x000D_
<main>_x000D_
<section>_x000D_
<h1>One</h1>_x000D_
<ul>_x000D_
</ul>_x000D_
</section>_x000D_
_x000D_
<section>_x000D_
<h1>Two</h1>_x000D_
</section>_x000D_
_x000D_
<section>_x000D_
<header>_x000D_
<h1>Three</h1>_x000D_
</header>_x000D_
<textarea></textarea>_x000D_
<footer>_x000D_
<p>Footer</p>_x000D_
</footer>_x000D_
</section>_x000D_
</main>_x000D_
_x000D_
<footer>_x000D_
<p>Footer</p>_x000D_
</footer>
_x000D_
Which looks like this - I want columns One and Two to shrink/grow to fit rather than being fixed:
My question is, is there a CSS-only workaround for flex-basis: content
, or an alternative way to realise this goal?
I can possibly live with fixing the column sizes as above, or using javascript, but I HAVE A DREAM DAMN IT.
It turns out that it was shrinking and growing correctly, providing the desired behaviour all along; except that in all current browsers flexbox wasn't accounting for the vertical scrollbar! Which is why the content appears to be getting cut off.
You can see here, which is the original code I was using before I added the fixed widths, that it looks like the column isn't growing to accomodate the text:
http://jsfiddle.net/2w157dyL/1/
However if you make the content in that column wider, you'll see that it always cuts it off by the same amount, which is the width of the scrollbar.
So the fix is very, very simple - add enough right padding to account for the scrollbar:
http://jsfiddle.net/2w157dyL/2/
main > section {_x000D_
overflow-y: auto;_x000D_
padding-right: 2em;_x000D_
}
_x000D_
It was when I was trying some things suggested by Michael_B (specifically adding a padding buffer) that I discovered this, thanks so much!
Edit: I see that he also posted a fiddle which does the same thing - again, thanks so much for all your help
I want columns One and Two to shrink/grow to fit rather than being fixed.
Have you tried: flex-basis: auto
or this:
flex: 1 1 auto
, which is short for:
flex-grow: 1
(grow proportionally)flex-shrink: 1
(shrink proportionally)flex-basis: auto
(initial size based on content size)or this:
main > section:first-child {
flex: 1 1 auto;
overflow-y: auto;
}
main > section:nth-child(2) {
flex: 1 1 auto;
overflow-y: auto;
}
main > section:last-child {
flex: 20 1 auto;
display: flex;
flex-direction: column;
}
Related:
Source: Stackoverflow.com