naughty boy naughty boy - 4 months ago 17
CSS Question

Make flex items on second row take remaining height of container

I am trying to create a layout with a header on top, underneath it a sidebar and the main content.

I would like to have the sidebar and the content view take over the vertical space left by the header. The problem is that the header can dynamically re-size so I cannot perform a

calc()
. My solution was to use the flexbox scheme.

I divided the viewport horizontally into two parts. One is the header and one is a wrapper for the sidebar and main content.

The sidebar is floated left and given a percentage of the width and the content is floated right and given the rest.

The problem is that I am trying to make the sidebar always be 100% height of the wrapper.

I tried
height: 100%
and
min-height: 100%
but these do not work.

I do not wish to absolutely position it since if the wrapper were to overflow with the main content, the sidebar would not expand accordingly.

Here is my pen: http://codepen.io/markt5000/pen/JXNXpW

As you can see the orange is the header and the red space is the wrapper with the sidebar and the content.

here is the layout



<div class="header">
</div>

<div class="row">

<div id="sidebar">
</div>

<div id="main-content">
</div>

</div>



Answer

There's no need for:

Flex properties have all the power you need to make the layout work. The key is to use flex: 1 to make items expand the full available length of the container.

So your header's height can be dynamic and the sidebar and main content can be made to consume whatever height remains. No scrollbars.

Here's your code with some revisions:

html { height: 100%; }

body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.outer-flex-container {
  height: 100%;
  display: flex;
  flex-direction: column;  /* main flex container stacks items vertically */
}

.header {
  height: 80px;            /* demo purposes; from your original code */
  background-color: orange;
}

.nested-flex-container {
  display: flex;           /* inner flex container stacks items horizontally */
  flex: 1;                 /* KEY RULE: tells this second flex item of main container
                                  to consume all available height */
  align-items: stretch;    /* KEY RULE: default setting. No need to include. Tells
                                  children to stretch the full length of the container
                                  along the cross-axis (vertically, in this case). */
}

.sidebar {
  flex-basis: 20%;        /* set width to 20% */
  background-color: aqua;
}

.content {
  flex: 1;                /* set width to whatever space remains */
  background: magenta;
}
<div class="outer-flex-container">

     <div class="header">HEADER</div><!-- main flex item #1 -->

     <div class="nested-flex-container"><!-- main flex item #2 -->
    
          <div class="sidebar">SIDEBAR</div><!-- inner flex item #1 -->
    
          <div class="content">MAIN CONTENT</div><!-- inner flex item #2 -->
    
     </div><!-- close inner flex container -->

</div><!-- close outer flex container -->

Revised Codepn