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>
CodePudding user response:
I have tried to add a fixed position to your example above and ended up with the result below. Only some css code was edited.
...
.a1 {
background: lightblue;
position : fixed;
width: 100%;
}
...
.b1 {
background: pink;
position: fixed;
width: 100%;
transform: translate(0, 100%);
}
See the full code at codepen.io here.
CodePudding user response:
Here is an example using grid. Flexbox likes to grow to fit its children so when you use it to explicitly set heights and make things scroll you're fighting that layout tool, grid works better in this case.
I removed some width declarations and the padding declaration on your root and body element which all do absolutely nothing!
html,
body {
margin: 0;
height: 100%;
font-size: 1em;
}
* {
box-sizing: border-box;
}
.outer {
height: 100%;
display: grid;
grid-template-rows: 2em 1fr;
background: white;
overflow: auto;
}
.a1 {
background: lightblue;
}
.a2 {
height: 100%;
display: grid;
grid-template-rows: 2em 1fr;
background: green;
overflow: auto;
}
.b1 {
background: pink;
}
.b2 {
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>