AdamAL
AdamAL

Reputation: 1681

How to add scroll to child of flex item?

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>

fiddle

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>

fiddle

How can I make this work?

And why doesn't the second fiddle work?

Added OP comments:

Upvotes: 16

Views: 15617

Answers (3)

Michael Benjamin
Michael Benjamin

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>


EDIT (based on revised question)

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 or max-height) or have white-space set to nowrap.

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

Upvotes: 8

RizkiDPrast
RizkiDPrast

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

kukkuz
kukkuz

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

Related Questions