Simon Ferndriger
Simon Ferndriger

Reputation: 4962

How does `flex-grow:0` get interpreted?

I wonder if flex-grow:0 in the Flexbox model means

If it means the latter, is it save to say that this is equal to width:auto and display:inline-block, i.e. it takes just as much width as needed to display?

Upvotes: 19

Views: 19590

Answers (2)

A few examples of flex-grow: 0

The following examples might be helpful for those learning flex-box.

Basically, flex-grow does the following:

  • check if the container is wider than all children
  • if yes, distribute the left-over space proportionally to the flex-grow of each child

So, if we have two children with e.g. flex-grow equal respectively to:

  • 1 and 1: give both the same share of the extra space
  • 1 and 2: give the second 2x more than the first
  • 0 and 1: give the second infinitely more than the first (1/0 = infinity), i.e. don't grow the first at all and grow the second to fill the rest of container
  • 0 and 0: none of them will grow, and the children can end up being smaller than the container. So 0 can be seen to be as a slightly magic value and simply meaning "never grow this" than a proportion in the more strict sense (since the meaning of 0/0 is not well defined).

Here's how the code below render on Chromium 85:

enter image description here

for (let container of document.getElementsByClassName('container')) {
  const widths = [];
  for (let child of container.children) {
    widths.push(child.offsetWidth)
  }
  container.insertAdjacentHTML('afterEnd', `<div>widths: ${widths.join(' ')}</div><br>`)
}
.container {
  display: flex;
  width: 400px;
}
.container .child-1 {
  background-color: red;
  height: 2em;
}
.container .child-2 {
  background-color: blue;
  height: 2em;
}
.container .subchild-1 {
  background-color: green;
}
.container .subchild-2 {
  background-color: yellow;
}
ruler
<div class="container"><div style="width: 50px; background-color: magenta;">50</div><div style="width: 50px; background-color: cyan;">50</div><div style="width: 50px; background-color: magenta;">50</div><div style="width: 50px; background-color: cyan;">50</div><div style="width: 50px; background-color: magenta;">50</div><div style="width: 50px; background-color: cyan;">50</div><div style="width: 50px; background-color: magenta;">50</div><div style="width: 50px; background-color: cyan;">50</div></div>

flex-grow 1 1. Adds 75 (175 = 100 + 75) to child-1 and 75 to child-2 (225 = 150 + 75)
<div class="container">
  <div class="child-1" style="flex-grow: 1;"><div class="subchild-1" style="width: 100px">100</div></div>
  <div class="child-2" style="flex-grow: 1;"><div class="subchild-2" style="width: 150px">150</div></div>
</div>

flex-grow 1 2. child-1 wants 100, child-2 wants 200. We have 100 left to 400. child-2 to grow 2x more than child-1 (33 vs 67).
<div class="container">
  <div class="child-1" style="flex-grow: 1;"><div class="subchild-1" style="width: 100px">100</div></div>
  <div class="child-2" style="flex-grow: 2;"><div class="subchild-2" style="width: 200px">200</div></div>
</div>

flex-grow 0 1. child-1 simply cannot grow, so child-2 takes up all remaining space.
<div class="container">
  <div class="child-1" style="flex-grow: 0"><div class="subchild-1" style="width: 50px">50</div></div>
  <div class="child-2" style="flex-grow: 1"><div class="subchild-2" style="width: 50px">50</div></div>
</div>

flex-grow 0 0. How much is 300 divided by 0? Doesn't matter, if neither can grow we go below the min.
<div class="container">
  <div class="child-1" style="flex-grow: 0"><div class="subchild-1" style="width: 50px">50</div></div>
  <div class="child-2" style="flex-grow: 0"><div class="subchild-2" style="width: 50px">50</div></div>
</div>

flex-grow 0 0. No more space left, all fits perfectly. flex-grow 0 does nothing.
<div class="container">
  <div class="child-1" style="flex-grow: 0"><div class="subchild-1" style="width: 100px">100</div></div>
  <div class="child-2" style="flex-grow: 0"><div class="subchild-2" style="width: 300px">300</div></div>
</div>

flex-grow 0 0. Minimal content size doesn't fit, nothing we can do about it.
<div class="container">
  <div class="child-1" style="flex-grow: 0"><div class="subchild-1" style="width: 100px">100</div></div>
  <div class="child-2" style="flex-grow: 0"><div class="subchild-2" style="width: 400px">400</div></div>
</div>

Upvotes: 3

Robert Koritnik
Robert Koritnik

Reputation: 105059

flex-grow:0 simply means that the item won't be resized during item size calculation to accommodate flex container's full main axis size.

Specification describes it as:

This <number> component sets flex-grow longhand and specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when positive free space is distributed. When omitted, it is set to 1.

I've emphasized main axis size above beacuse you should know that flex-grow is related to main axis of the flex container which can be width or height dimension depending on flex-direction and writing directionality of user browser.

Therefore we can't assume being equal to your assumption.

But when we're talking about flex-direction: row and writing directionality LRTB (left to right, top to bottom) then they do work in the similar fashion as width: auto;. Items do appear as inlined, but they still don't render the same because no whitespace is being added for each line break in HTML source as we normally see with usual inline elements.

How about width: 0?

Flex item width is associated with flex-basis property rather than grow factor. Although flex properties have precedence over width or height of items when grow and shrink factors are defined and non-zero.

Upvotes: 25

Related Questions