htmlcssflexbox

Div stretch to all the available space but no more


I have a simple setup with:

# Header
# Content
# Footer

I want Content to stretch to all available space (if it needs more show scroll), and it works:

body {
  margin: 0;
  font-size: 2em;
}

.container {
  background-color: bisque;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.header {
  background-color: #846267;
  height: 50px;
}

.content {
  background-color: #AEB4A9;
  /* height: calc(100vh - 100px); */
  overflow-y: auto;
  height: 100%;
}

.footer {
  background-color: #D89A9E;
  height: 50px;
}
<html>
<body>

<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
      aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
      aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
      occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
      aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
      Duis
      aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
      occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
      aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
      Duis
      aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
      occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
      aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
      Duis
      aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
      occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
  <div class="footer">Footer</div>
</div>
</body>
</html>

Header and Footer are always visible and Content stretches and shrinks as needed to fill all the available space but no more (even if it overflows).

As you can see for this it is not even needed flexbox.


But if I go for a slightly more complicated setup:

# Header
# Content
  ## H3
  ## Subcontent
# Footer

And now I want the Subcontent to stretch to all available space (and if it needs more, show scroll). Then everything is a mess:

body {
  margin: 0;
  font-size: 2em;
}

.container {
  background-color: bisque;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.header {
  background-color: #b2cf5a;
  height: 50px;
}

.content {
  background-color: #AEB4A9;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.sub-content {
  overflow-y: auto;
  flex-grow: 1;
  background-color: #dbe2d6;
}

.footer {
  background-color: #D89A9E;
  height: 50px;
}
<html>
<body>
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <h3>Content</h3>
    <div class="sub-content">
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
        aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
        aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
        aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        Duis
        aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
        aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        Duis
        aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
        aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        Duis
        aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
    </div>
  </div>
  <div class="footer">Footer</div>
</div>
</body>
</html>

There are 2 scroll bars. Only one should be necessary.

The sub-content is taken more space than it should be

The Footer is not visible because sub-content is taken up too much space.

enter image description here

I tryed with and without flexbox, but I can not manage to keep all the page layout elements visible. And force Subcontent to streches and shrinks properly.


Solution

  • I found the successful combination. The needed changes from the code snipped are:

         .content {
           background-color: #AEB4A9;
    -      height: 100%;
           display: flex;
           flex-direction: column;
    +      flex-grow: 1;
         }
     
         .sub-content {
           overflow-y: auto;
           flex-grow: 1;
    +      flex-basis: 0;
           background-color: #dbe2d6;
         }
    

    I saw that the main problem was in the size of the content element. It was bigger that it should be. Using flex-grow: 1 instead of height: 100% fixed this.

    Then I saw that using flex-basis: 0 in the sub-content was preventing the sub-content from growing more than the available space.

    Here is the full snipped working

    body {
      margin: 0;
      font-size: 2em;
    }
    
    .container {
      background-color: bisque;
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    
    .header {
      background-color: #b2cf5a;
      height: 50px;
    }
    
    .content {
      background-color: #AEB4A9;
      display: flex;
      flex-direction: column;
      flex-grow: 1;
    }
    
    .sub-content {
      overflow-y: auto;
      flex-grow: 1;
      flex-basis: 0;
      background-color: #dbe2d6;
    }
    
    .footer {
      background-color: #D89A9E;
      height: 50px;
    }
    <div class="container">
      <div class="header">Header</div>
      <div class="content">
        <h4>Content</h4>
        <div class="sub-content">
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis
            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis
            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis
            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
        </div>
      </div>
      <div class="footer">Footer</div>
    </div>