Chrome Does Not Expand Flex Parent According to Children's Content

Chrome does not expand flex parent according to children's content

This appears to be a bug in Chrome.

In this section of code:

.items span {
flex-basis: 25px;
flex-shrink: 0;
}

... Chrome is not respecting the fixed 25px width. Or, at least, the container is not recognizing the space. It looks like the container is being sized before all item calculations are factored in.

The simple workaround is to use width instead of flex-basis.

.items span {
flex-shrink: 0;
width: 25px;
}

revised demo


UPDATE

Bug Report

Flex-basis is being ignored when sizing nested flex containers.

"Yeah this is kind of a sucky consequence of a bug we have, perhaps combined with an unfortunate spec consequence..."

"When the outer flexbox finds the desired size of the inner flexbox, it asks for its max-content size (see LayoutFlexibleBox::computeInnerFlexBaseSizeForChild). But here's where the bug comes in, the max-content size does not take flex-basis into account, only width properties/actual content. That's why adding an explicit width fixes the bug."

Why doesn't the nested flex parent height grow with children?

This is the logical behavior and its how the algorithm of flexbox works. To start, let's remove some properties especially the flex-shrink:0.

html,body{  height:100%;  margin:0;}.grand-parent{  height:100%;  overflow:auto;  display:flex;}.parent{  display:flex;  flex-direction:column;  min-height:100%;  width:100%;}
.child{ height:1500px; width:100%; display:flex;}
.green{ background:green;}
.blue{ background:blue;}
<div class="grand-parent">  <div class="parent">    <div class="child green"></div>    <div class="child blue"></div>  </div></div>

Chrome / Safari not filling 100% height of flex parent

Solution

Use nested flex containers.

Get rid of percentage heights. Get rid of table properties. Get rid of vertical-align. Avoid absolute positioning. Just stick with flexbox all the way through.

Apply display: flex to the flex item (.item), making it a flex container. This automatically sets align-items: stretch, which tells the child (.item-inner) to expand the full height of the parent.

Important: Remove specified heights from flex items for this method to work. If a child has a height specified (e.g. height: 100%), then it will ignore the align-items: stretch coming from the parent. For the stretch default to work, the child's height must compute to auto (full explanation).

Try this (no changes to HTML):

.container {    display: flex;    flex-direction: column;    height: 20em;    border: 5px solid black}
.item { display: flex; /* new; nested flex container */ flex: 1; border-bottom: 1px solid white;}
.item-inner { display: flex; /* new; nested flex container */ flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */ /* width: 100%; <-- remove; unnecessary */ /* display: table; <-- remove; unnecessary */ }
a { display: flex; /* new; nested flex container */ flex: 1; /* new */ align-items: center; /* new; vertically center text */ background: orange;
/* display: table-cell; <-- remove; unnecessary */ /* vertical-align: middle; <-- remove; unnecessary */}
<div class="container">  <div class="item">    <div class="item-inner">      <a>Button</a>    </div>  </div>
<div class="item"> <div class="item-inner"> <a>Button</a> </div> </div>
<div class="item"> <div class="item-inner"> <a>Button</a> </div> </div></div>

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.

Image extends height of flex parent, but behaves with a weird hack in chrome and safari

Is this what you are looking to do?
You can also see it here: https://codepen.io/teanbiscuits/pen/GRJmPgo

#parent {  height: 100vh;  display: grid;  grid-template-columns: 1fr;  grid-template-rows: 1fr auto;  border:2px solid green;  border-radius:20px;  overflow:hidden;}
#child { position:relative;}
#child img { position:absolute; width: 100%; height: 100%; object-fit: contain;}
#text { background-color:green;}
<div id="parent">  <div id="child">    <img src="https://i.picsum.photos/id/1005/400/1000.jpg" />  </div>  <div id="text">    <h2>some title here</h2>    <p>Some description here</p>  </div></div>

Prevent flex item from exceeding parent height and make scroll bar work

Short Answer

Instead of flex: 1, use flex: 1 1 1px.

Make these two adjustments in your code:

#messagelist {
/* flex:1; */
flex: 1 1 1px; /* new */
}

#messagecontents {
/* flex:1; */
flex: 1 1 1px; /* new */
}

revised codepen


Explanation

In most cases, as you have noted, adding min-height: 0 to flex items in a column-direction container is enough to correct the problem.

In this case, however, there's an additional obstacle: flex-basis.

You're applying the following rule to flex items #messagelist and #messagecontents: flex: 1.

This is a shorthand rule that breaks down to:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

(source: https://www.w3.org/TR/css-flexbox-1/#flex-common)


2019 UPDATE: Since the posting of this answer in 2018, it appears that Chrome's behavior has changed and is now uniform with Firefox and Edge. Please keep that in mind as you read the rest of this answer.


In Chrome, flex-basis: 0 is enough to trigger an overflow, which generates the scrollbars. (2019 update: This may no longer be the case.)

In Firefox and Edge, however, a zero flex-basis is insufficient. This is probably the more correct behavior in terms of standards compliance as MDN states:

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

Well, flex-basis: 0 meets none of those conditions, so an overflow condition should not occur. Chrome has probably engaged in an intervention (as they often do).

An intervention is when a user agent decides to deviate slightly from a standardized behavior in order to provide a greatly enhanced user experience.

To meet the "standardized behavior", which would enable an overflow to occur in Firefox and Edge, give flex-basis a fixed height (even if it's just 1px).

Flexbox overflow not expanding parent container in Chrome

Use flex-shrink: 0 on .flex-tree-parent

/* WorkPackage Treeview */
.flex-tree,.flex-tree2,.flex-tree-content,.flex-tree-content2,.flex-tree-bottom,.flex-tree-parent,.flex-tree-children,.flex-tree-child-button { display: -ms-flexbox; display: -webkit-flex; display: flex;}
.flex-tree,.flex-tree2,.flex-tree-content,.flex-tree-content2,.flex-tree-parent { -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column;}
.flex-tree { min-width: 240px; max-width: 245px; min-height: 180px; max-height: 180px; position: absolute; border-style: solid; border-width: 1px; z-index: 100;}
.flex-tree2 { min-width: 240px; max-width: 245px; min-height: 380px; max-height: 380px; position: absolute; border-style: solid; border-width: 1px; z-index: 100;}
.flex-tree-content { min-height: 150px; max-height: 150px; background-color: White; border-bottom-style: solid; border-bottom-width: 1px; overflow-y: scroll;}
.flex-tree-content2 { min-height: 350px; max-height: 350px; background-color: White; border-bottom-style: solid; border-bottom-width: 1px; overflow-y: scroll;}
.flex-tree-bottom { align-items: center; justify-content: center; min-height: 30px; max-height: 32px; background-color: Gray; border-bottom-style: solid; border-bottom-width: 1px;}
.flex-tree-parent { margin-left: 20px; flex-shrink: 0;}
.flex-tree-parent>.flex-tree-children:first-child { margin-left: 7px;}
.flex-tree-children { -webkit-flex-direction: row-reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; margin: 3px; margin-left: 27px; min-width: 101px; max-width: 101px; min-height: 20px; min-height: 20px;}
.flex-tree-content>.flex-tree-children:first-child { margin-top: 15px; margin-left: 7px;}
.flex-tree-content2>.flex-tree-children:first-child { margin-top: 15px; margin-left: 7px;}
.flex-tree-child-button { width: 16px; height: 16px; background-image: url('https://cdn2.iconfinder.com/data/icons/bwpx/icons/toggle_minus.gif'); background-repeat: no-repeat; cursor: pointer; order: 2;}
.flex-tree-child { text-align: center; width: 80px; height: 20px; background-color: GreenYellow; border-style: solid; border-width: 1px; color: black; margin-left: 5px; order: 1;}
.flex-tree-close { line-height: 7px; width: 75px; height: 25px; cursor: pointer; margin: 3px;}
<div class="flex-tree" style="left: 50px; top: 50px;">  <div class="flex-tree-content">    <div class="flex-tree-children" id="2">      <div class="flex-tree-child-button" id="2"></div><a class="flex-tree-child" id="2">1</a></div>    <div class="flex-tree-children" id="6"><a class="flex-tree-child" id="6">1,1</a></div>    <div class="flex-tree-parent" id="8">      <div class="flex-tree-children" id="8">        <div class="flex-tree-child-button" id="8"></div><a class="flex-tree-child" id="8">1,2</a></div>      <div class="flex-tree-parent" id="19">        <div class="flex-tree-children" id="19">          <div class="flex-tree-child-button" id="19"></div><a class="flex-tree-child" id="19">1,2,1</a></div>        <div class="flex-tree-children" id="26">          <a class="flex-tree-child" id="26">1,2,1,1</a></div>

</div> <div class="flex-tree-children" id="29"><a class="flex-tree-child" id="29">1,2,2</a></div> <div class="flex-tree-children" id="30"><a class="flex-tree-child" id="30">1,2,3</a></div> </div> <div class="flex-tree-children" id="9"><a class="flex-tree-child" id="9">1,3</a></div> <div class="flex-tree-children" id="23"><a class="flex-tree-child" id="23">1,4</a></div> <div class="flex-tree-children" id="24"><a class="flex-tree-child" id="24">New task</a></div> </div> <div class="flex-tree-bottom"> <button class="flex-tree-close">Close</button> </div></div>
<div class="flex-tree2" style="left: 400px; top: 50px;"> <div class="flex-tree-content2"> <div class="flex-tree-children" id="2"> <div class="flex-tree-child-button" id="2"></div><a class="flex-tree-child" id="2">1</a></div> <div class="flex-tree-children" id="6"><a class="flex-tree-child" id="6">1,1</a></div> <div class="flex-tree-parent" id="8"> <div class="flex-tree-children" id="8"> <div class="flex-tree-child-button" id="8"></div><a class="flex-tree-child" id="8">1,2</a></div> <div class="flex-tree-parent" id="19"> <div class="flex-tree-children" id="19"> <div class="flex-tree-child-button" id="19"></div><a class="flex-tree-child" id="19">1,2,1</a></div> <div class="flex-tree-children" id="26"> <a class="flex-tree-child" id="26">1,2,1,1</a></div>

</div> <div class="flex-tree-children" id="29"><a class="flex-tree-child" id="29">1,2,2</a></div> <div class="flex-tree-children" id="30"><a class="flex-tree-child" id="30">1,2,3</a></div> </div> <div class="flex-tree-children" id="9"><a class="flex-tree-child" id="9">1,3</a></div> <div class="flex-tree-children" id="23"><a class="flex-tree-child" id="23">1,4</a></div> <div class="flex-tree-children" id="24"><a class="flex-tree-child" id="24">New task</a></div> </div> <div class="flex-tree-bottom"> <button class="flex-tree-close">Close</button> </div></div>

Why is a flex item limited to parent size?

You need to consider flex-shrink. As you can read here:

The flex-shrink CSS property specifies the flex shrink factor of a
flex item. Flex items will shrink to fill the container according to
the flex-shrink number, when the default size of flex items is larger
than the flex container.

body {
margin: 0;
}
* {
box-sizing: border-box;
}

.parent {
min-height: 100vh;
width: 50vw;
margin: 0 auto;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}

.child {
border: 1px solid blue;
width: 150%;
flex-shrink: 0; /* added this */
}
<div class="parent">
<div class="child">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet tellus cras adipiscing enim eu turpis. Neque aliquam vestibulum morbi blandit. Sem integer vitae justo eget magna.
</div>
</div>


Related Topics



Leave a reply



Submit