2

I am trying to get my mind around flex box layout and now considering flex-direction: column option.

HTML

<div class="container">
    <div class="item">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Quaerat similique nihil, mollitia
        voluptates iste eos atque unde repellendus iure voluptatibus nulla explicabo laboriosam, harum, eum dicta.
        Maiores quia aliquid in.</div>
    <div class="item">
        Lorem
    </div>
</div>

CSS

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

.item{
    flex: 1;
}

As long as our screen displays the first item div's text in multiple rows, the items end up with different main sizes (heights). It was rather surprising to me as row flex-direction in this case would hold the same main sizes of items (widths).

To find out how it happens, I delved into the spec.

9.2. Line Length Determination

2 Determine the available main and cross space for the flex items. For each dimension, if that dimension of the flex container’s content box is a definite size, use that; ... otherwise, subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value. This might result in an infinite value.

4 Determine the main size of the flex container using the rules of the formatting context in which it participates.

As far as I'm concerned, it is the very case when the available space in the main (vertical) dimension is an infinity value. So it puzzles me how it's possible to determine the container's main size (step 4), noting that sizes of the items are still uncalculated at this point (the container is a block element, so its height value is dependent on its children).

Can anybody provide some explanation and point me out to the place in the spec where our items finally get different height values?1

1: In accordance with the step 4 of 9.7. Resolving Flexible Lengths, main size of an item should be a fraction of its grow factor to the sum of the items' grow factors multiplyed by the free space (the container's height). We have the same grow factors, so why do we see different items heights?

Ilya Loskutov
  • 1,967
  • 2
  • 20
  • 34
  • 1
    You don't have any height specified on the items, so the height of each item is determined—by default—by the height of the content. – Michael Benjamin Jan 05 '22 at 18:50
  • @MichaelBenjamin `flex-basis` is set to 0 by the `flex: 1;` shorthand, isn't it? So I expect all height of the container should be considered as free space and distributed between the items as it described in the aforementioned 9.7 section. – Ilya Loskutov Jan 05 '22 at 18:55
  • Free space is distributed when there is free space to distribute. Since you have no height defined on the container either, it also defaults to the height of the content ( `height: auto`). Hence, no free space. However, give the container some height and... https://jsfiddle.net/t3pjx19y/ – Michael Benjamin Jan 06 '22 at 02:44

1 Answers1

0

You are running it a complex case where another specification need to be considered and also the min-height constraint.

When using flex:1 the browser is setting flex-basis: 0%. Pay attention to the % because all the trick is there. You have a percentage so you need a reference to resolve it and we are dealing with a height auto so the reference doesn't exist. At the end it's like you didn't set any flex-basis that's why you see no difference.

Now if you use flex-basis: 0px you will have a different behavior

.container {
  display: flex;
  flex-direction: column;
  border: 1px solid;
}

.item {
  flex: 1 1 0px;
  border: 1px solid red;
  min-height: 0;
}
<div class="container">
  <div class="item">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Quaerat similique nihil, mollitia voluptates iste eos atque unde repellendus iure voluptatibus nulla explicabo laboriosam, harum, eum dicta. Maiores quia aliquid in.</div>
  <div class="item">
    Lorem
  </div>
</div>

Note that I have also introduced min-height: 0. Without it, nothing will happen because an element cannot shrink past its content size.

Now if you set flex-basis to 0px, each element will have an initial height equal to 0px so the height of the container will also be equal to 0px. End of the story! flex-grow and flex-shrink will do nothing since there is no positive or negative free space.


It's different when dealing with a row direction because the container width doesn't depend on its content and is full width. In such case you will have free space for the flex-grow and you end with equal width items.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • This answer is more a personal interpretation of what I already know. Might need to dig more into the Spec to grab all the relevant sections – Temani Afif Jan 05 '22 at 20:27