Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make flex items on second row take remaining height of container

Tags:

html

css

flexbox

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>

like image 323
naughty boy Avatar asked Mar 22 '16 23:03

naughty boy


People also ask

How do you make a flex object take up your remaining space?

Use the flex-grow property to make a flex item consume free space on the main axis. This property will expand the item as much as possible, adjusting the length to dynamic environments, such as screen re-sizing or the addition / removal of other items.

How do you make a div fill the height of the remaining space?

Another way of making a <div> fill the remaining space is to use the CSS position property. Just set the position to “absolute” to stretch the <div>.

Can I set height for Flex item?

By default, a flex container has the following width and height assigned. width: auto; height: auto; But you can set a fixed height and width to the flex container.

How do you make a flex item break to the next line?

The solution is to force them by adding a collapsed row (height 0) which takes up the entire width of the container, making it occupy an entire row, thus pushing the 3rd item on the next row. Think of it like a <br> tag.


1 Answers

There's no need for:

  • height, min-height or calc on your flex items
  • absolute positioning
  • floats (in fact, they're useless because floats are ignored in a flex formatting context)

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

like image 188
Michael Benjamin Avatar answered Oct 06 '22 12:10

Michael Benjamin