Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make two flex items each 50% height of parent

Tags:

html

css

flexbox

I am using css flex layout to build a dashboard and would like to put two widgets (one on top of the other) inside of a flex item and make them 50% height of their parent at all times (regardless of content). So if my html is:

<div class="flex-container">
  <div class="flex-item">
    <div class="widget" id="w1">
      widget 1 content
    </div>
    <div class="widget" id="w2">
      widget 2 content
    </div>
  </div>
</div>

and my css looks like:

.flex-container {
  display: flex;
  flex-direction: column;
}
.flex-item {
  flex: 1;
}

How can I get the two .widgets to always occupy 50% height of .flex-item?

I've tried:

.flex-item {
  flex: 1;
  display: flex;
}
.widget {
  flex: 1;
}

But this only works when the content in both widgets are the same.

I've worked up a more elaborate jsfiddle to better illustrate my issue.

Thanks in advance!

like image 222
AndyPerlitch Avatar asked Mar 23 '16 05:03

AndyPerlitch


1 Answers

When you say that flex: 1 only works when the content in both widgets are the same, that is not correct. That would defeat the purpose of flex: 1.

flex: 1 tells flex items to distribute container space evenly among themselves. If there are four flex items with flex: 1, each will take 25%. Three would take 33.33%. And two flex items will take 50%. This is regardless of content quantity.

See this illustration: DEMO


The problem you're having is not clear in the code you posted in the question. However, it's apparent in your fiddle demo.

You have a main container with a height: 400px. You also have a rule adding 10px padding all-around to your divs. This adds 20px height to each div. You also have a header with height: 2em.

When you account for the extra heights the layout works.

Try these adjustments:

HTML (no changes)

CSS

div {
    box-shadow: inset 0 0 0 1px rgba(30, 100, 200, 0.5);
    padding: 10px;                    /* sneaky villain */
    font-family: arial;
}

h1, p { margin: 0; }

#main-wrapper {
    height: 400px;                    /* primary height */
    display: flex;
    flex-direction: column;
}

#header {
    flex-shrink: 0;
    height: 2em;                      /* header height */
}

#main-column-wrapper {
    flex: 1;
    display: flex;
    flex-direction: row;
    height: calc(100% - 2em - 20px);  /* primary height - header height - padding */
}

#side-column {
    width: 20%;
    flex-shrink: 0;
}

#main-column {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: calc(100% - 40px);      /* main-column-wrapper height - padding (2 divs) */
}

#widget1,
#widget2 {
    flex: 1;
    flex-shrink: 0;
    overflow: auto;
}

Revised Fiddle

Another option would be to use box-sizing: border-box to adjust for the padding. Learn more here: https://css-tricks.com/box-sizing/

like image 133
Michael Benjamin Avatar answered Nov 04 '22 16:11

Michael Benjamin