ChatGPT解决这个技术问题 Extra ChatGPT

Why does flexbox stretch my image rather than retaining aspect ratio?

Flexbox has this behaviour where it stretches images to their natural height. In other words, if I have a flexbox container with a child image, and I resize the width of that image, the height doesn't resize at all and the image gets stretched.

div { display: flex; flex-wrap: wrap; } img { width: 50% }

Heading

Paragraph

What causes this?

In Firefox and IE works fine. In Chrome you can fix with align-self:flex-start in the image. I don't know why, maybe the default value in chrome is stretch.
Also adding height: 100%; to the img fixes the problem, I would like to know why it stretches the image too.
@blonfu, the default value in all browsers is align-items: stretch / align-self: stretch. If you add a border around each item and remove wrap, you'll notice all items stretch in all browsers: codepen.io/anon/pen/oLXBVx?editors=1100
Ok.I learn this but with images work differently in chrome and the others browser. Chrome don't respect the aspect ratio if you don't define the height.
@blonfu, Yes. No question there are browser inconsistencies and more granular levels.

T
TylerH

It is stretching because align-self default value is stretch. Set align-self to center.

align-self: center;

See documentation here: align-self


Yes but the others browser mantaining the aspect ratio in the images. Chrome nor applies flex-basis in img
I think align-self: start; may be a stronger answer because images should vertically align to the TOP of their containers (not center) like any styleless image (no css) would. Either way, both answers fix the stretching. So it depends on what OP wants of course - just didn't get that 'vertically centered' impression from OP's post.
If you don't define a width on an image and it's in a flex-container, it will stretch to 100%. align-self: [flex-start, center...others] will prevent the image from taking 100% of the flex-containers width. align-self:center fixes it of course, but if you want your image to start from the beginning or end of container use align-items: flex-start or flex-end
You can also put align-items: center (or whatever alignment fits your needs) on the parent.
Doesn't work for me:
F
FutureCake

The key attribute is align-self: center:

.container { display: flex; flex-direction: column; } img { max-width: 100%; } img.align-self { align-self: center; }

Without align-self:

With align-self:


i
isapir

I faced the same issue with a Foundation menu. align-self: center; didn't work for me.

My solution was to wrap the image with a <div style="display: inline-table;">...</div>


It's about flexbox though.
This is a solution for flexbox. The image and div are inside a flexbox container.
A
Aakash

Adding margin to align images:

Since we wanted the image to be left-aligned, we added:

img {
  margin-right: auto;
}

Similarly for image to be right-aligned, we can add margin-right: auto;. The snippet shows a demo for both types of alignment.

Good Luck...

div { display:flex; flex-direction:column; border: 2px black solid; } h1 { text-align: center; } hr { border: 1px black solid; width: 100% } img.one { margin-right: auto; } img.two { margin-left: auto; }

Flex Box




J
Jongwoo Lee

I had a similar issue while making my navigation bar, but none of the above worked for me.

My solution was adding height: 100% for the image.

If you're aligning the items horizontally, add width: 100% instead.

EDIT: Chrome seems to add this value by default now, but you'll need to add this for compatibility.


Yes, Thank you! This worked for me. But I had to put the image in a wrapper, set the height and width of the wrapper then set the image itself to 100% width.
m
mohamed ali

It is stretching because align-self default value is stretch. there is two solution for this case : 1. set img align-self : center OR 2. set parent align-items : center

img {

   align-self: center
}

OR

.parent {
  align-items: center
}

X
Xin

Use one of the CSS settings below: contain or cover is most popular

.my-img {
  object-fit: contain;
}

or

.my-img {
  object-fit: cover;
}

Z
Zach Jensz

I had a similar issue, my solution was adding flex-shrink: 0; to the image.