3

I can't understand, how in my case flex affects the proportions of image. I've found on my own, that it is because of width: 100% which is set for img tag. But I don't understand, why it works in that way?

How sizes are calculated for each flex element in my case and why it doesn't get full space evenly distributed between 2 flex elements?

Here's the code:

#about {
  border: 2px solid blue;
}

.row {
  display: flex;
  border: 2px solid black;
}

img {
  display: block;
  width: 100%;
  height: 100%;
}

.column {
  flex-grow: 1;
  border: 2px dashed red;
}
<section id="about">
  <div class="row">
    <div class="column">
      <img src="https://i.stack.imgur.com/yat2N.jpg" alt="">
    </div>
    <div class="column"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur quibusdam dicta dolore suscipit quidem, hic nihil aliquid officia porro illum! Necessitatibus cupiditate, sapiente cum recusandae tenetur dolore veritatis in temporibus perferendis.
      Ex corrupti voluptatibus eaque aliquam quis soluta veniam non dicta repellendus ea iure temporibus assumenda placeat accusantium quae iste, corporis maxime dolorum quisquam neque est sint asperiores doloribus. Quibusdam ducimus saepe distinctio
      illum veniam voluptates amet quod perferendis dolorem, deleniti mollitia. Ab aperiam, ea itaque tempore molestias ullam sint accusamus totam reiciendis laborum. At natus consequatur ex officia. Porro dolor accusamus blanditiis nam commodi provident
      assumenda facere adipisci perferendis. </div>
  </div>
</section>

Here's JS Fiddle

MichaelLearner
  • 429
  • 4
  • 14
  • 1
    Does this answer your question? [Why does width and height of a flex item affect how a flex item is rendered?](https://stackoverflow.com/questions/44878379/why-does-width-and-height-of-a-flex-item-affect-how-a-flex-item-is-rendered) More so, `Flexbox` model states elements in a single row will shrink in size as the amount of available space is reduced. For example, if you have a row of elements and you decrease the width of the browser, the elements will shrink in width as the width of the containing element reduces. This can be prevented by setting min/max-width on the flex children – Kameron Jan 21 '22 at 17:51
  • @カメロン Thank you for providing me with a link of great information about Flexbox rendering properties and how `height` overrides `align-items: stretched`, but I still don't know how to apply those knowledges to my problem. Cause I don't understand, how property `width: 100%` of `img` tag affects flex item in a such way, that it renders so differently from its sibling (even if we set 'flex-grow: 1` to both of them, first flex item with the image is rendered differently and has less space, why?) – MichaelLearner Jan 21 '22 at 18:16
  • Have you had a look at [W3C documentation](https://www.w3.org/TR/css-flexbox-1/#flexibility)? – dale landry Jan 22 '22 at 01:23

2 Answers2

1

First, you should note that flex-grow is by default equal to 1 so you don't need to set it. Then, you need to understand "cyclic dependency" and "percentage sizing".

In your case, you have a image that should be 100% of its parent width but its parent is a flex item and its width depend on its content (the image width as well).

I have explained a similar behavior here: How do browsers calculate width when child depends on parent, and parent's depends on child's. The same apply in your case and the width:100% will disable the minimum contribution of the image size. It's like the image doesn't exist initially.

Here is the steps the browser will perform.

First, each column is sized with its content. No shrink is occurring (It's like setting flex-shrink:0)

#about {
  border: 2px solid blue;
}

.row {
  display: flex;
  border: 2px solid black;
}

img {
  display: block;
  width: auto;
}

.column {
  flex-shrink: 0;
  border: 2px dashed red;
}
<section id="about">
  <div class="row">
    <div class="column">
      <img src="https://i.stack.imgur.com/yat2N.jpg" alt="">
    </div>
    <div class="column"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur quibusdam dicta dolore suscipit quidem, hic nihil aliquid officia porro illum! Necessitatibus cupiditate, sapiente cum recusandae tenetur dolore veritatis in temporibus perferendis.
      Ex corrupti voluptatibus eaque aliquam quis soluta veniam non dicta repellendus ea iure temporibus assumenda placeat accusantium quae iste, corporis maxime dolorum quisquam neque est sint asperiores doloribus. Quibusdam ducimus saepe distinctio
      illum veniam voluptates amet quod perferendis dolorem, deleniti mollitia. Ab aperiam, ea itaque tempore molestias ullam sint accusamus totam reiciendis laborum. At natus consequatur ex officia. Porro dolor accusamus blanditiis nam commodi provident
      assumenda facere adipisci perferendis. </div>
  </div>
</section>

If you check the width of each column you will get 1604 for the first one and 5097 for the second. You may get slightly different values but the most important is to notice the difference which is the key.

Now both column need to shrink to fit the container width. Let's suppose the container width is equal to Xpx. We will have an overflow (also called free negative space) equal to (5097 + 1604) - X = 6701 - X.

The width formula for each column will be:

1st = 1604 - ((X - 6701) * 1604/6701) = 1604 - ((6701 - X) * 0.24)
2nd = 5097 - ((X - 6701) * 5097/6701) = 5097 - ((6701 - X) * 0.76)

The first thing to notice from the above is that the sum will give you X which is the logical result since both column need to shrink until they fit the container width.

And if you perform some calculation you can find the width of each column and you will notice that the second one is always bigger.

If X = 1000 you will have 235.76 / 764.24

If X = 800 you will have 187.6 / 612.24

This is the logic behind the flexbox algorithm. Both columns should keep the same proportion when shrinking (the bigger item remain the bigger one after shrinking)

At the end, the browser will place the image inside the fist column having 100% of the calculated width.


Without width:100% you will face the minimum constraint of the image element which will prevent the first column from shrinking past the image size. Your image size is equal to 1604 so your first column cannot go smaller so the second column will try to shrink to 0 but it cannot go smaller than the longest word which gives you the following result.

#about {
  border: 2px solid blue;
}

.row {
  display: flex;
  border: 2px solid black;
}

img {
  display: block;
}

.column {
  border: 2px dashed red;
}
<section id="about">
  <div class="row">
    <div class="column">
      <img src="https://i.stack.imgur.com/yat2N.jpg" alt="">
    </div>
    <div class="column"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur quibusdam dicta dolore suscipit quidem, hic nihil aliquid officia porro illum! Necessitatibus cupiditate, sapiente cum recusandae tenetur dolore veritatis in temporibus perferendis.
      Ex corrupti voluptatibus eaque aliquam quis soluta veniam non dicta repellendus ea iure temporibus assumenda placeat accusantium quae iste, corporis maxime dolorum quisquam neque est sint asperiores doloribus. Quibusdam ducimus saepe distinctio
      illum veniam voluptates amet quod perferendis dolorem, deleniti mollitia. Ab aperiam, ea itaque tempore molestias ullam sint accusamus totam reiciendis laborum. At natus consequatur ex officia. Porro dolor accusamus blanditiis nam commodi provident
      assumenda facere adipisci perferendis. </div>
  </div>
</section>

Both columns are overflowing. The first one is equal to the image width and the second one to the longest word.

You can disable this by using min-width:0 on the column:

#about {
  border: 2px solid blue;
}

.row {
  display: flex;
  border: 2px solid black;
}

img {
  display: block;
}

.column {
  border: 2px dashed red;
  min-width:0;
}
<section id="about">
  <div class="row">
    <div class="column">
      <img src="https://i.stack.imgur.com/yat2N.jpg" alt="">
    </div>
    <div class="column"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur quibusdam dicta dolore suscipit quidem, hic nihil aliquid officia porro illum! Necessitatibus cupiditate, sapiente cum recusandae tenetur dolore veritatis in temporibus perferendis.
      Ex corrupti voluptatibus eaque aliquam quis soluta veniam non dicta repellendus ea iure temporibus assumenda placeat accusantium quae iste, corporis maxime dolorum quisquam neque est sint asperiores doloribus. Quibusdam ducimus saepe distinctio
      illum veniam voluptates amet quod perferendis dolorem, deleniti mollitia. Ab aperiam, ea itaque tempore molestias ullam sint accusamus totam reiciendis laborum. At natus consequatur ex officia. Porro dolor accusamus blanditiis nam commodi provident
      assumenda facere adipisci perferendis. </div>
  </div>
</section>

You will get the same width calculated initially but now the image inside the column will overflow.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
-1

Dont use flex-grow:1 instead you can use col-6 for both siblings. you will get your desire output

Mirza Irtiza
  • 154
  • 7
  • That would be a valid solution if OP wanted each element to take up 50%. However, using Bootstrap and `col-6` would involve a `row` which would then involve `flex`. Thus, brings us right back to the question about how flex affects the image. – Kameron Jan 21 '22 at 18:34