HTML5 Flexible Box Model Height Calculation

HTML5 flexible box model height calculation

I've been wrestling with this myself, but have finally managed to come up with a solution.

See this jsFiddle, although I have only added webkit prefixes so open in Chrome.

You basically have 2 issues which I will deal with separately.

  1. Getting the child of a flex-item to fill height 100%
    • Set position:relative; on the parent of the child.
    • Set position:absolute; on the child.
    • You can then set width/height as required (100% in my sample).
  2. Fixing the resize scrolling "quirk" in Chrome
    • Put overflow-y:auto; on the scrollable div.
    • The scrollable div must have an explicit height specified. My sample already has height 100% but if none is already applied you can specify height:0;

See this answer for more information on the scrolling issue.

How can I make Flexbox children 100% height of their parent?

Use align-items: stretch

Similar to David Storey's answer, my workaround is:

.flex-2 {
display: flex;
align-items: stretch;
}

Note that height: 100% should be removed from the child component (see comments).

Alternatively to align-items, you can use align-self just on the .flex-2-child item you want stretched.

Control height of Flex Box

This will work better. I updated the flexbox rules a little.

Src: https://css-tricks.com/using-flexbox/

<html lang="en"><head>    <title>Welcome to my site</title>    <meta charset="utf-8"/>    <style type="text/css">        #mommy {            display: -webkit-box;  /* iOS 6-, Safari 3.1-6 */            display: -ms-flexbox;  /* IE 10 */            display: -webkit-flex; /* Safari 6.1+. iOS 7.1+ */            display: flex;         /* Modern browsers */              border: 2px solid blue;                      width: 700px;            height: 300px;        }
#mommy div { -webkit-box-flex: 1; /* iOS 6-, Safari 3.1-6 */ width: 20%; /* For old syntax, otherwise collapses. */ -ms-flex: 1; /* IE 10 */ -webkit-flex: 1; /* Safari 6.1+. iOS 7.1+ */ flex: 1; /* Modern browsers */ padding: 20px; margin: 10px; border-radius: 20px; height: 100px; }
#kid1 { border: 2px solid red; background: green; }
#kid2 { border: 2px solid red; background: yellow; }
#kid3 { border: 2px solid red; background: red; }
#kid4 { border: 2px solid red; background: orange; }
</style></head>
<body><section id="mommy"> <div id="kid1">Child 1</div> <div id="kid2">Child 2</div> <div id="kid3">Child 3</div> <div id="kid4">Child 4</div></section></body></html>

Make a div fill the height of the remaining screen space

2015 update: the flexbox approach

There are two other answers briefly mentioning flexbox; however, that was more than two years ago, and they don't provide any examples. The specification for flexbox has definitely settled now.

Note: Though CSS Flexible Boxes Layout specification is at the Candidate Recommendation stage, not all browsers have implemented it. WebKit implementation must be prefixed with -webkit-; Internet Explorer implements an old version of the spec, prefixed with -ms-; Opera 12.10 implements the latest version of the spec, unprefixed. See the compatibility table on each property for an up-to-date compatibility status.

(taken from https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)

All major browsers and IE11+ support Flexbox. For IE 10 or older, you can use the FlexieJS shim.

To check current support you can also see here:
http://caniuse.com/#feat=flexbox

Working example

With flexbox you can easily switch between any of your rows or columns either having fixed dimensions, content-sized dimensions or remaining-space dimensions. In my example I have set the header to snap to its content (as per the OPs question), I've added a footer to show how to add a fixed-height region and then set the content area to fill up the remaining space.

html,body {  height: 100%;  margin: 0;}
.box { display: flex; flex-flow: column; height: 100%;}
.box .row { border: 1px dotted grey;}
.box .row.header { flex: 0 1 auto; /* The above is shorthand for: flex-grow: 0, flex-shrink: 1, flex-basis: auto */}
.box .row.content { flex: 1 1 auto;}
.box .row.footer { flex: 0 1 40px;}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->
<div class="box"> <div class="row header"> <p><b>header</b> <br /> <br />(sized to content)</p> </div> <div class="row content"> <p> <b>content</b> (fills remaining space) </p> </div> <div class="row footer"> <p><b>footer</b> (fixed height)</p> </div></div>

Flexible Box Layout in Opera

There's a known bug in Blink (used by Chrome and Opera) regarding flex items that are "stretch-aligned" (like in your test).

https://code.google.com/p/chromium/issues/detail?id=341310

Your test is valid, and the spec is very clear on this:

http://www.w3.org/TR/css3-flexbox/#algo-stretch

You should however consider inserting a <!DOCTYPE html> line at the top, so that browsers don't enter quirks mode. Blink fails differently with your test, depending on quirks mode or not. :)



Related Topics



Leave a reply



Submit