CSS - How do I make the container fit all available grandparents' heights?

I am working on a web application and have a layout issue.

Here is the expected design, with 3 main parts:

  • Article title
  • The content of the article
  • Article footer

the expected design

It's pretty easy to implement this design with CSS Flexbox.

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

.article {
  display: flex;
  flex-direction: column;
}

  .article-header {
    background-color: orange;
  }
  
  .article-footer {
    background-color: green;
  }
  
  .article-content {
    flex-grow: 1;
    background-color: CornflowerBlue;  
  }
 
      

<article class="article">
  <header class="article-header">Header</header>
  <div class="article-content">Article Content</div>
  <footer class="article-footer">Footer</footer>
</article>
      

Run codeHide result


However, in a real application, HTML elements are much deeper and sometimes out of control (considering using third party components or switching in Angular / React)

Therefore, HTML usually looks like this:

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

.article {
  display: flex;
  flex-direction: column;
}

  .article-header {
    background-color: orange;
  }
  
  .article-footer {
    background-color: green;
  }

  .article-wrapper {
    flex-grow: 1;
  }
 
  .article-content {
    flex-grow: 1;
    background-color: CornflowerBlue;  
  }
 
      

<article class="article">
  <header class="article-header">Header</header>
  <div class="article-wrapper">
    <div>
      <div>
        <div class="article-content">
           Article Content.
           Can I fit all available height?
        </div>
       </div>
      </div>
    </div>
  <footer class="article-footer">Footer</footer>
</article>
      

Run codeHide result


It looks like in this case the only way to make the .article-content fit all available height is to add these styles to each container along the path from the .article-wrapper to the article-content:

display: flex;
flex-direction: column;
flex-grow: 1;

      

But as I mentioned, this is quite problematic because sometimes the nesting is quite deep, or the container elements are generated by third party components.

Please let me know if there are better ways to achieve the desired design.

Thank you in advance!

+3


source to share


1 answer


Only direct children of a flex container become flex, and as such can apply the property flex-grow: 1

.

So for that you need to provide article-wrapper

its descendants with div

up to article-content

flex properties , where all 3 should be both a flex container and a flex item.

.article-wrapper,
.article-wrapper > div,
.article-wrapper > div > div {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
}

      

Simply put, it .article-wrapper

is a flexible container for the former div

, the former div

will be a flexible element for .article-wrapper

, but also a flexible container for the latter div

, etc.

Update



Also, according to the posted image, article-content

should scroll when the content exceeds its height, and for that I added overflow: auto

to the rulewrapper-content

Snippet example

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

.article {
  display: flex;
  flex-direction: column;
}

  .article-header {
    background-color: orange;
  }
  
  .article-footer {
    background-color: green;
  }

  .article-wrapper {
     overflow: auto;
  }

  .article-wrapper,
  .article-wrapper > div,
  .article-wrapper > div > div {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
  }

  .article-content {
    flex-grow: 1;
    background-color: CornflowerBlue;  
  }
      

<article class="article">
  <header class="article-header">Header</header>
  <div class="article-wrapper">
    <div>
      <div>
        <div class="article-content">
           Article Content.
           Can I fit all available height?
           <br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
           Scroll overflowed content<br><br>
        </div>
       </div>
      </div>
    </div>
  <footer class="article-footer">Footer</footer>
</article>
      

Run codeHide result


+1


source







All Articles