3

I can't understand, how flex: 1 affects the height of an element, even if I set the height of the section to 500px, the image will go out of the section.

Here's the code:

#about {
  height: 500px;
}

.row {
  display: flex;
}

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

.column {
  flex: 1;
}
<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>

Can you please explain, why and how flex: 1 affects the height of an img or another items.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
MichaelLearner
  • 429
  • 4
  • 14

3 Answers3

2

It doesn't, align-items has a default value of normal, which in flexbox contexts is the same as align-items: stretch.

This causes the two flex children (the .column with the image and the .column with the text) to be the same height.

When the text is taller than the image, the image container stretches. If the image is taller, the text container stretches.

To remove this effect, add

.row {
  align-items: flex-start;
}

To have the items aligned to the top without the flex children stretching.

romellem
  • 5,792
  • 1
  • 32
  • 64
1

Firstly, you've defined the container with display: flex. The default flex-direction is row.

This means the the main axis is horizontal.

Hence, the flex property is controlling width. It has no affect on height.

You would have to shift the main axis (by adding flex-direction: column) in order to apply the flex property vertically.

Secondly, if you change the height: 500px to min-height: 500px, you will solve the overflow problem (without having to change flex-direction).

#about {
  min-height: 500px;
  border: 2px solid blue;
}

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

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

.column {
  flex: 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>

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Can you please explain, why `flex: 1`, affects the `height` of the `img`? If I do `flex-basis: 100%`. Image will stretch in the same way, but why it affects not only horizontal axis, but also vertical axis? – MichaelLearner Jan 20 '22 at 19:20
  • Because the image is set to the default `height: auto`, which means its height will expand naturally when the width expands. Your `height: 100%` on the `img` is being ignored because it's not in compliance with spec rules ([see here](https://stackoverflow.com/a/31728799/3597276)). – Michael Benjamin Jan 20 '22 at 19:28
  • That isn't true. Because the container is `stretch` alignment, a `height: 100%` on the image (the child of the container) will be `100%` of that container's height. – romellem Jan 20 '22 at 20:56
  • If you remove `height: 100%` on the `img`, there's no difference. @romellem – Michael Benjamin Jan 20 '22 at 21:05
  • Yes, it does make a difference depending on the height of the other flex child. See [this image](https://i.stack.imgur.com/FdtE1.png) using the same CSS in the example above. The only difference between those two screenshots is the `img` has `height: 100%` set in the first screenshot. – romellem Jan 20 '22 at 22:01
  • What browser are you testing on? @romellem – Michael Benjamin Jan 20 '22 at 22:19
  • It's not a browser thing, I see the same stretching happen on Chrome 97, Firefox 95, and Safari 15. That is an intended outcome _because_ the parent container of the image (the `.column`) is stretching due to it's parent (the flex container `.row`) having a default value of `align-items: stretch`. – romellem Jan 20 '22 at 22:25
  • But what you're missing is that percentage heights on elements default to `height: auto` when there's no height defined on the parent element, like in this case. I've noticed that some browsers are beginning to ignore this rule completely, so they may work in some cases. But I wouldn't rely on it because it's non-standard behavior. Regardless, as you said, `align-items: stretch` is having an effect. @romellem – Michael Benjamin Jan 20 '22 at 22:45
  • My guess is this is standardized behavior, although you bring up a good point. I think it has to do with flex-items having _definite_ sizing - https://www.w3.org/TR/css-flexbox-1/#definite-sizes – romellem Jan 21 '22 at 01:16
  • @MichaelBenjamin can you please tell, if we set `flex-grow: 1` (replacing `flex: 1` with `flex-grow: 1`) of `column` without affecting `flex-basis`, the image will shrink and will not be half of `row` element. Why it works in that way? [JS fiddle](https://jsfiddle.net/qo1v4Lrz/2/) – MichaelLearner Jan 21 '22 at 08:33
0

you can read about it here, its a great and thorough post.

Edit based on your edit

flex: 1; is equivalent to flex: 1 1 0;

so when you call it, it is actually like:

flex-grow : 1;    ➜ The div will grow in same proportion as the window-size       
flex-shrink : 1;  ➜ The div will shrink in same proportion as the window-size 
flex-basis : 0;   ➜ The div does not have a starting value as such and will 
                     take up screen as per the screen size available for
                     e.g:- if 3 divs are in the wrapper then each div will take 33

based on what you want to achieve, there are several solutions,

  1. try flex: 1 1 auto;, flex-basis: auto; means "look at my width or height property".
  2. You can try using object-fit: contain or object-fit: cover on the image.

in any case, regarding your question - with flex-grow: 1; all the elements will grow to take up an equal portion of the .parent element.

so basically, it defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.

so in your code you are telling the image to fill the entire space of its parent div (because it is alone inside it)

Guy Nachshon
  • 2,411
  • 4
  • 16