I'm trying to create a full-height layout where only the bottom "part" of the layout scrolls. That is, a couple fixed title bars and then the whole area below scrolls.
Could be done with tables or absolute positioning, but seems like flexbox is the modern answer. And it seems to work fine with a flat column flexbox with three divs and flex: 1; overflow: auto
in the last div. But not when flexboxes are nested. When I use nested flexboxes, I always get a scrollbar on the whole page, never a scrollbar in the main content area.
This flat flexbox layout works as intended:
outer
b1
b2
b3
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.outer {
background: white;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.b1 {
background: lightblue;
}
.b2 {
background: pink;
}
.b3 {
flex: 1;
background: green;
overflow: auto;
}
<div class='outer'>
<div class='b1'>
b1
</div>
<div class='b2'>
b2
</div>
<div class='b3'>
b3<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/> b3
<br/>
</div>
</div>
This nested structure doesn't work as intended:
outer
a1
a2
b1
b2
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.outer {
background: white;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.a1 {
background: lightblue;
}
.a2 {
flex: 1;
background: green;
display: flex;
flex-direction: column;
}
.b1 {
background: pink;
}
.b2 {
flex: 1;
background: yellow;
overflow: auto;
}
<div class='outer'>
<div class='a1'>
a1
</div>
<div class='a2'>
<div class='b1'>
b1
</div>
<div class='b2'>
b2<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/>
</div>
</div>
</div>
Your b2 is doing exactly what you want, it's just flowing out of the bottom of a2. Add overflow: hidden
to a2 to stop this behaviour:
.a2 {
overflow: hidden;
}
html,
body {
margin: 0;
height: 100%;
}
.outer {
background: white;
height: 100%;
display: flex;
flex-direction: column;
}
.a1 {
background: lightblue;
}
.a2 {
flex: 1;
background: green;
display: flex;
flex-direction: column;
overflow: hidden;
}
.b1 {
background: pink;
}
.b2 {
flex: 1;
background: yellow;
overflow: auto;
}
<div class='outer'>
<div class='a1'>
a1
</div>
<div class='a2'>
<div class='b1'>
b1
</div>
<div class='b2'>
b2<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/> b2
<br/>
</div>
</div>
</div>