I'm trying to create 2 column full height design by using flexbox. When I add scrolling to whole middle part then I have a strange behavior. It seems that flex-grow/stretch doesn't grow/stretch other items if parent container has a scrollbar.
Here is my fiddle. Code also given below:
html, body {
height: 100%;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container section {
flex: 1 1 auto;
overflow-y: auto;
min-height: 0px;
}
#container footer {
background-color: gray;
}
aside {
width : 100px;
background-color: blue;
}
article{
width: 100%;
display:flex;
flex-direction: column;
}
article > div{
flex: 1 1 auto;
}
#content {
display:flex;
}
<section id="container" >
<header id="header" >This is a header</header>
<section id="content">
<aside>
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
test<br />
</aside>
<article id="article" >
<div>
This is the content that
<br />
With a lot of lines.
<br />
With a lot of lines.
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines.
<br />
<br />
This is the content that
<br />
With a lot of lines.
<br />
</div>
<footer id="footer" >This is a page footer</footer>
</article>
</section>
<footer id="footer" >This is a footer</footer>
</section>
Basically i'm trying to cover 2 scenarios. It works fine if i don't need to scroll but once i have a scroll the items doesn't stretch correctly:
To make this layout work in latest Firefox & Chorme as of today (revising this answer from 2016), I made the following changes:
Added margin: 0
to body
to allow the container
to flex to the viewport height.
Wrap you the contents on #content
element in another section
and make it a column flexbox.
Make the inner section
a full-height flexbox and give min-height: max-content
and flex: 1
.
See demo below:
html,
body {
height: 100%;
margin: 0; /* ADDED */
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container > section { /* ADDED > selector */
display: flex; /* ADDED */
flex-direction: column; /* ADDED */
flex: 1 1 auto;
overflow-y: auto;
min-height: 0px;
}
#container > section > section{ /* ADDED */
display: flex;
height: 100%;
min-height: max-content; /* fixes chrome */
flex: 1; /* fixes firefox */
}
#container footer {
background-color: gray;
}
aside {
width: 100px;
background-color: blue;
min-height: content;
}
article {
width: 100%;
display: flex;
flex-direction: column;
}
article>div {
flex: 1 1 auto;
}
<section id="container">
<header id="header">This is a header</header>
<section id="content">
<section>
<aside>
test<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br />
</aside>
<article id="article">
<div>
This is the content that
<br /> With a lot of lines.
<br /> With a lot of lines.
<br /> This is the content that
<br /> With a lot of lines.
<br />
<br /> This is the content that
<br /> With a lot of lines.
<br />
<br /> This is the content that
<br /> With a lot of lines.
<br />
</div>
<footer id="footer">This is a page footer</footer>
</article>
</section>
</section>
<footer id="footer">This is a footer</footer>
</section>
The above solution is hacky at best and shows us why a flexbox is weak in 2D layouts. The answer is it is just not designed for it. But CSS Grids
are - see how easily everything falls into place:
Make #container
a full viewport high grid element.
Make the middle section
a grid container with grid-template-columns: 100px 1fr
along with overflow property and you are almost done.
See demo below:
body {
margin: 0;
}
#container {
display: grid;
width: 50%;
height: 100vh;
background-color: red;
}
header, footer {
background-color: gray;
}
#container section {
display: grid;
grid-template-columns: 100px 1fr;
overflow-y: auto;
}
aside {
background-color: blue;
}
article {
display: flex;
flex-direction: column;
}
article > div {
flex: 1 1 auto;
}
<section id="container">
<header id="header">This is a header</header>
<section id="content">
<aside>
test<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br /> test
<br />
</aside>
<article id="article">
<div>
This is the content that
<br /> With a lot of lines.
<br /> With a lot of lines.
<br /> This is the content that
<br /> With a lot of lines.
<br />
<br /> This is the content that
<br /> With a lot of lines.
<br />
<br /> This is the content that
<br /> With a lot of lines.
<br />
</div>
<footer id="footer">This is a page footer</footer>
</article>
</section>
<footer id="footer">This is a footer</footer>
</section>