Skip to content Skip to sidebar Skip to footer

Nested Flexboxes Works Differently Across Browsers

I have a small example of a nested flexbox setup: http://jsfiddle.net/ThomasSpiessens/MUrPj/12/ In this example the following applies: CSS 'box' classes use flexbox properties o

Solution 1:

Unless you need that extra div, remove it. There is sometimes a difference between the height of an element and its length along the main axis (column orientation), which is causing some confusion here. Basically, it looks like it is taller than the browser believes it to be, which is why height: 100% doesn't work like you expect (I'm not certain which behavior is correct in this instance).

For whatever reason, promoting the element to a flex container works.

http://jsfiddle.net/MUrPj/14/

<divclass="box fullSize"><divclass="boxHeader">HEADER</div><divclass="boxContent box"><divclass="boxHeader moregreen">INNER HEADER</div><divclass="boxContent red">CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT</div><divclass="boxFooter moreblue">INNER FOOTER</div></div><divclass="boxFooter">FOOTER</div></div>

Solution 2:

This question has been linked for a specific problem: How to make nested elements in a flex box fill the whole height? The short answer is:

Use display:flex on the child and avoid height:100%. Here is a simplified example on codepen.

CourtDemone explained it well (more here):

According to the flexbox spec, an align-self:stretch value (the default for a flex'd element) changes only the used value of an element's cross-size property (in this case, height). Percentages however are calculated from the specified value of the parent's cross-size property, not it's used value.

Solution 3:

I've found a solution without removing the extra-div.

You need to make boxContent relative positioned and its containing box absolute.

With attaching an extra css class to the inner div:

<div class="boxContent">
    <div class="box fullSize innerBox">

and following css:

.boxContent {
  ...
    position: relative;
}
.innerBox{
    position: absolute;
    top: 0px;
    bottom: 0px;
}

here's the updated jsfiddle: http://jsfiddle.net/MUrPj/223/

This question is pretty old, but this might be helpful for future visitors

Solution 4:

This JsFiddle is the minimum needed CSS attributes to get nested flexboxes to work. I've shown it for column; if you are doing this within a row, remove the two "flex-direction: column"s. [In this trivial example, removing those won't change anything, because there is only one child of each flexbox. But as soon as you add a second child, you'll be working in either a row or a column.]

HTML:

<div id="e1">
  <div id="e2">
    <div id="e3">    
    </div>
  </div>
</div>

CSS:

html, body, #e1 {
  height: 100%; width: 100%;
}
#e1 {
  background-color: #ff0000;
  display: flex;
  flex-direction: column;
}
#e2 {
  background-color: #ffff00;
  /* Won't work if remove either of the next 2 lines - a box collapses. */flex: 1;
  display: flex;
  flex-direction: column;
}
#e3 {
  background-color: #00ff00;
  flex: 1;
}

In my experience, Safari 13 (both MacOS and iOS) is more finicky (re nested flex items) than Chrome 77, Firefox 69, or even Edge 18. While in this simple example, all 3 react the same, I had a more complex situation which worked in all but Safari. Nevertheless, the code shown here -- especially the two lines in #e2 after "Won't work if remove either of the next 2 lines" -- is the essence of what made my more complex situation work in Safari.

In addition, if having difficulties, first step is to remove all "percent" height attributes within the nested elements. Here, that means #e1 is permitted to have height: 100% - this is within the context of its parent, which is not a flex container. But #e2 and #e3 should not declare % heights.

Having nested elements with heights that are not relative to their parent (pixels, ems, vh) are fine, AFAIK. Note that vh works, because it is relative to window size, which isn't affected by the nested flex containers' (#e1, #e2) heights. So that calculation logic is easy for browser to get right.


As requested, example of nesting four deep. Uses class names to make it easier.

HTML:

<divclass="fb-outer"><divclass="fb-middle"><divclass="fb-middle"><divclass="fb-inner"></div></div></div></div>

CSS:

html, body, .fb-outer {
  height: 100%; width: 100%;
}
.fb-outer {
  background-color: #ff0000;
  display: flex;
  flex-direction: column;
}
.fb-middle {
  background-color: #ffff00;
  /* Won't work if remove either of the next 2 lines. */flex: 1;
  display: flex;
  flex-direction: column;
}
.fb-inner {
  background-color: #00ff00;
  flex: 1;
}

Solution 5:

*,*::before,*::after {
margin:0;
padding:0;
box-sizing:border-box;

}
body {
width:100%;
height:100vh;
background-color:purple;
}

.fullSize {
   width: 100%;
   height: 100%; 
    margin: 0;
    padding: 0;
 
}



.box {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
  background-color: brown;
}

/* line 7, ../../app/styles/_layout.scss */.boxHeader {
background-color: green;
}

/* line 12, ../../app/styles/_layout.scss */.boxContent {
  -ms-flex: 10 auto;
  -webkit-flex: 10 auto;
  flex: 10 auto;
  -webkit-box-flex: 1.0;
  background-color: yellow;
}

/* line 18, ../../app/styles/_layout.scss */.boxFooter {
  background-color: cornflowerblue;
}

.moreblue {
    background-color: blue;
}

.moregreen {
    background-color: darkgreen;
}

.red {
    background-color: red;
}
<divclass="box fullSize"><divclass="boxHeader">HEADER</div><divclass="boxContent"><divclass="box"><divclass="boxHeader moregreen">INNER HEADER</div><divclass="boxContent red">
                     CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT  
                </div><divclass="boxFooter moreblue">INNER FOOTER</div></div></div><divclass="boxFooter">FOOTER</div></div>

Post a Comment for "Nested Flexboxes Works Differently Across Browsers"