5

I'm trying to build a navigation panel which has a fixed-height primary navbar at the top, a fixed-height secondary navbar fixed to the bottom of the screen, and a container in between which fills the remaining space and is scrollable depending on the length of the list of items inside.

I'm learning to use flexbox and thought I could use flex-grow and overflow: hidden to accomplish this, however I'm running into some trouble.

Here's a fiddle

html,
body {
  height: 100%;
}

.container-main {
  display: flex;
  height: 100%;
  flex-flow: column;
}

.nav-bar {
  display: flex;
  height: 36px;
  background-color: grey;
}

.container-dd {
  height: 100%;
  display: flex;
  flex-flow: column;
}

.dd-fill {
  display: flex;
  flex-flow: column;
  flex: 1 1 auto;
  background-color: green;
  overflow: hidden;
}

.dd-bot {
  display: flex;
  height: 100px;
}
<div class="container-main">
  <div class="nav-bar">top nav bar</div>
  <div class="container-dd">
    <div class="dd-fill">
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
    </div>
    <div class="dd-bot">sticky footer</div>
  </div>
</div>

You can see from the fiddle that the content that doesn't fit inside the div dd-fill is inaccessible and there's no scrollbar. Also the fixed height of the secondary navbar is not being enforced. Does anyone know why it's behaving like this? Thanks in advance.

Pete
  • 57,112
  • 28
  • 117
  • 166
Weardian
  • 211
  • 4
  • 13

2 Answers2

3

You can solve your overflow by changing hidden to auto and use min-height (I sometimes add max-height too to ensure it doesn't grow in bigger screens) instead of height for your top and bottom bits:

html,
body {
  height: 100%;
  margin: 0;
}

.container-main {
  display: flex;
  height: 100%;
  flex-flow: column;
}

.nav-bar {
  display: flex;
  min-height: 36px;         /* use min-height */
  background-color: grey;
}

.container-dd {
  height: 100%;
  display: flex;
  flex-flow: column;
}

.dd-fill {
  display: flex;
  flex-flow: column;
  flex: 1 1 auto;
  background-color: green;
  overflow: auto;            /* use auto so scrollbar appears */
}

.dd-bot {
  display: flex;
  min-height: 100px;       /* use min-height */
}
<div class="container-main">
  <div class="nav-bar">top nav bar</div>
  <div class="container-dd">
    <div class="dd-fill">
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
      <p>list item</p>
    </div>
    <div class="dd-bot">sticky footer</div>
  </div>
</div>
Pete
  • 57,112
  • 28
  • 117
  • 166
  • That did the job! Thank you. – Weardian Aug 01 '18 at 09:36
  • This introduces another scrollbar, which I don't think is an ideal experience. My suggestion would be to use expand collapse pattern using a button to avoid scroll bar. – Signcodeindie Apr 17 '19 at 13:46
  • @Signcodeindie it didn't use to, very strange. Anyway, if you were looking for a sticky footer with scrollable content, I would have had the header and footer in the same parent container which would make it easier to make the middle scrollable: https://jsfiddle.net/5uoqwp8s/ – Pete Apr 17 '19 at 14:14
0

The problem is you have set a fixed height of 100% and overflow: hidden for the .container-dd

.conrtainer-dd {
   height: 100%;
   overflow: hidden;
}

The fixed height of 100% prevents .container-dd from expanding to incorporate all the additional content and overflow: hidden is preventing the scrollbar from appearing. Change your style to this.

.container-dd {
   ...
   height: auto;
   min-height: 100%;
   overflow: auto;
   ...
}

Also, do this.

.dd-fill {
   height: auto;
   overflow: hidden;
}
Deiknymi
  • 196
  • 3
  • 10