cssscrollable

Scrollable content without using position:absolute and wrapper DIV


How to make the section element below scrollable and take 100% of its parent height?

*{ margin: 0 }
main{
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: black;
}

header, footer{
  flex: 0 0 auto;
  background: red;
}

content{
  flex: 1 1 auto;
  display: flex:
  flex-direction: column;
}

content nav{
  background: green;
  flex: 0 0 auto;
}

content section{
  flex: 1 1 auto;
  background: blue;
  overflow-y: auto;
  max-height: 100%; /* <- problem */
  
  p{
    flex: 0 0 auto;
  }
}

ul{
  flex: 1 1 auto;
  
  li{
     height: 200px;
  }
}
<main>
  <header>header</header>
  <content>
    <nav>nav</nav>
    <section>
      <ul>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
      </ul>
      <p>after list</p>
    </section>
  </content>
  <footer>footer</footer>
</main>

If I put a fixed pixel height on it, like max-height: 200px it works as expected (it scrolls), but how to make this height variable/fill remaining height of the parent?


Solution

  • While you have specified the max-height to be 100% you don't actually want it to be 100%, you want it to take the remaining space which is provided by your flex rules which are appropriate. Hence that's not the issue.

    Your problem is simply that you do not provide the initial size of the flex item. The flex property only governs how it flexes from the initial. Hence all you need is to provide a height value to your content styles which govern how small it can get. If you want it to disappear in favor of the footer you can go with 0 like so:

    *{ margin: 0 }
    main{
      width: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
      background: black;
    }
    
    header, footer{
      flex: 0 0 auto;
      background: red;
    }
    
    content{
      height: 0; /* <- content size */
      flex: 1 1 auto;
      display: flex;
      flex-direction: column;
    }
    
    content nav{
      background: green;
      flex: 0 0 auto;
    }
    
    content section{
      flex: 1 1 auto;
      background: blue;
      overflow-y: auto;
      /* max-height: 100%;  <- not needed */
      
      p{
        flex: 0 0 auto;
      }
    }
    
    ul{
      flex: 1 1 auto;
      
      li{
         height: 200px;
      }
    }
    <main>
      <header>header</header>
      <content>
        <nav>nav</nav>
        <section>
          <ul>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
            <li>item</li>
          </ul>
          <p>after list</p>
        </section>
      </content>
      <footer>footer</footer>
    </main>