Reputation: 1681
With a flex container with a fixed height, I can make a flex item scrollable by setting overflow: auto
, like so:
page {
display: flex;
flex-flow: row wrap;
height: 200px;
}
left-panel {
flex: 1;
display: block;
background: lightblue;
}
//main {flex: 5; display: block;}
header {
background: turquoise;
display: block
}
//main-content-wrapper {flex: 4; display:flex; flex-direction: column}
right-panel {
flex: 1;
overflow: auto;
}
content-panel {
background: pink;
display: block;
}
content {
height: 1000px;
display: block;
}
<page>
<left-panel>left-panel
<br/>(static)</left-panel>
<right-panel>
<header>
header
<br/>(static)
</header>
<content-panel>
<content>
content
<br/>(scrolls)
</content>
</content-panel>
</right-panel>
</page>
But I would like to make a child of the flex item scroll instead.
I would think that setting height: 100%
on the flex item and overflow: auto
on the child element I want to scroll would work, but it does not:
page {
display: flex;
flex-flow: row wrap;
height: 200px;
}
left-panel {
flex: 1;
display: block;
background: lightblue;
}
//main {flex: 5; display: block;}
header {
background: turquoise;
display: block
}
//main-content-wrapper {flex: 4; display:flex; flex-direction: column}
right-panel {
flex: 1;
height: 100%;
}
content-panel {
background: pink;
display: block;
overflow: auto;
}
content {
height: 1000px;
display: block;
}
<page>
<left-panel>left-panel
<br/>(static)</left-panel>
<right-panel>
<header>
header
<br/>(static)
</header>
<content-panel>
<content>content
<br/>(scrolls)</content>
</content-panel>
</right-panel>
</page>
How can I make this work?
And why doesn't the second fiddle work?
Added OP comments:
I can see there are several related questions, but the ones I found are either not directly applicable, or mention workarounds to bugs that may have been fixed since.
I would like to avoid using explicit height calculations to reduce coupling of components.
I could convert the right-panel into a nested flexbox with flex-direction: column
, but I was hoping to avoid that.
In case a flat structure (like in the second fiddle) is not possible without an explicit height calculation, it would be nice with an explanation of why. Could it be considered a bug with flexbox or am I misunderstanding something fundamental about css?
Upvotes: 16
Views: 15617
Reputation: 371251
If you're applying overflow: auto
to an element so it can launch a vertical scrollbar, then also give it a height limitation.
In this case, you just need to add height: 100%
to the element you want to make scrollable.
content-panel {
background: pink;
display: block;
overflow: auto;
height: 100%; /* NEW */
}
Of course, you'll need to adjust the actual percentage value to subtract the height of the header. Maybe something like this:
height: calc(100% - 80px)
OR, perhaps a better approach (and consistent with your added comments rejecting fixed heights), just make right-panel
a column-direction flex container:
page {
display: flex;
flex-flow: row wrap;
height: 200px;
}
left-panel {
flex: 1;
display: block;
background: lightblue;
}
header {
background: turquoise;
display: block
}
right-panel {
flex: 1;
height: 100%;
display: flex; /* NEW */
flex-direction: column; /* NEW */
}
content-panel {
background: pink;
overflow: auto;
}
content {
height: 1000px;
display: block;
}
<page>
<left-panel>left-panel
<br/> (static)</left-panel>
<right-panel>
<header>
header
<br/>(static)
</header>
<content-panel>
<content>content
<br/>(scrolls)</content>
</content-panel>
</right-panel>
</page>
With regard to the overflow
property:
The
overflow
property specifies whether to clip content, render scrollbars or just display content when it overflows its block level container.In order for the
overflow
property to have an effect, the block level container must either have a bounding height (height
ormax-height
) or havewhite-space
set tonowrap
.
Upvotes: 8
Reputation: 1725
your content-panel
already has height 1000px
and your content
has overflow:auto
. The only thing you missed is you did not specify the content-panel
height
. content-panel height
must < content height
in order for it to display scroll bar
<content-panel>
<content>
content
</br>(scrolls)
</content>
</content>
Upvotes: 0
Reputation: 42352
Make your right-panel
a column flexbox
and add flex:1
to content-panel
- see demo below:
page {
display: flex;
flex-flow: row wrap;
height: 200px;
}
left-panel {
flex: 1;
display:block;
background: lightblue;
}
header {
background: turquoise;
display:block;
}
right-panel {
flex: 1;
display: flex;/*Added this*/
flex-direction: column;/*Added this*/
height: 100%;
}
content-panel {
background: pink;
display:block;
overflow: auto;
flex:1; /*Added this*/
}
content {
display: block;
height: 1000px;
}
<page>
<left-panel>left-panel
<br/>(static)</left-panel>
<right-panel>
<header>
header
<br/>(static)
</header>
<content-panel>
<content>
content
<br/>(scrolls)
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
<br/>more content here
</content>
</content-panel>
</right-panel>
</page>
Upvotes: 1