An <img> placed directly inside a display: flex row container renders taller and visibly distorted instead of at its natural size. What causes that, and how do you fix it?
answer
- the cross axis has an opinionated default
- align-items starts at stretch
- auto cross size is what gets stretched
- align-self on the item opts it out
- object-fit changes painting, not box size
basics
~20 sA flex container stretches items along the cross axis by default, so an image with no set height is stretched to the height of the tallest item on the line while its width stays intrinsic, distorting it. Stop the stretch with align-self: flex-start or an explicit size.
solid answer
~50 sFlex containers align items on the cross axis with `align-items: stretch` by default. In a row container the cross axis is vertical, so any item whose height is `auto` grows to the line's height. An `<img>` is a flex item like any other, so its box is stretched to match the tallest sibling while its width is still its intrinsic width — the picture is scaled non-uniformly and looks squashed or elongated. The fixes are all about giving the cross size something other than `auto` to resolve to: `align-self: flex-start` (or `center`, or `baseline`) on the image opts it out of stretching, `align-items` on the container does the same for every item, and setting an explicit `height` also stops it. If you need the image to fill a stretched box without distorting, keep the stretch and add `object-fit: cover` or `contain`, which changes how the picture fits its box rather than how the box is sized.
code
css · 15 lines.media {
display: flex;
gap: 1rem;
}
/* Stretched: height is auto, so the flex line's height wins. */
.media > img.broken {
width: 120px;
}
/* Natural height: the item opts out of cross-axis stretching. */
.media > img.fixed {
width: 120px;
align-self: flex-start;
}go deeper
Be ready to name the default align-items: stretch as the cause and to write align-self: flex-start on the image as the fix. Knowing the symptom on sight is most of what is asked here.
Explain that stretch only applies when the cross size is auto, name which axis is the cross axis for row and column containers, and separate align-self (box geometry) from object-fit (how the picture fills the box).
Show the diagnosis path — compare rendered against intrinsic size, note that the distortion changes when a sibling's height changes — and discuss reserving space with aspect-ratio so the layout does not shift when the image loads.
Own the convention: whether shared media components ship with alignment opted out by default, and how the team prevents aspect-ratio bugs from reaching production through design-review or visual-regression checks.
## What is actually happening Every direct child of a flex container becomes a flex item, images included. Flex layout sizes items on two axes: the **main axis** (the direction set by `flex-direction`) and the **cross axis** (perpendicular to it). In `flex-direction: row` the main axis is horizontal and the cross axis is vertical. The container's `align-items` property controls the cross axis, and its initial value is `stretch`. Stretch means: if the item's cross size is `auto` and it has no auto margin on that axis, make it fill the flex line. So a row of items all become as tall as the tallest one — that is the familiar "equal height columns for free" behaviour, and it is usually what you want for boxes of text. Applied to an `<img>` it is usually not what you want. The image's height is `auto`, so it gets stretched to the line's height. Its width, however, was already resolved on the main axis from the intrinsic width. The result is a box whose width and height no longer match the picture's aspect ratio, and the raster is scaled to fill it — a portrait photo next to a tall block of text ends up stretched vertically. ```css .card { display: flex; /* row, align-items: stretch */ gap: 1rem; } /* .card > img is now as tall as the text column next to it */ ``` The column-direction version of the same bug is even more common: in `flex-direction: column` the cross axis is horizontal, so an image stretches to the **full width** of the container and gets blown up beyond its natural size. ## The fixes, and what each one actually does **Opt the item out of stretching.** ```css .card > img { align-self: flex-start; } ``` `align-self` on the item overrides the container's `align-items` for that item alone. `flex-start`, `flex-end`, `center`, and `baseline` all leave the cross size as `auto`, so the image uses its natural height. Use `align-items` on the container instead when *no* item should stretch. **Give the cross size a definite value.** `height: 200px` on the image also defeats stretch, because stretch only applies when the cross size is `auto`. Pair it with `width: auto` or `object-fit` if you care about the aspect ratio. **Keep the stretch, fix the picture.** Sometimes a stretched box is exactly the design — a hero image that fills a row. Then leave the box alone and control how the bitmap fills it: ```css .card > img { object-fit: cover; /* fill the box, crop the overflow */ object-position: center; } ``` `object-fit: cover` scales the image uniformly and crops; `contain` scales it uniformly and letterboxes. Neither changes the box's size — they change the relationship between the box and the picture inside it. This is the important distinction to state in an interview: `align-self` changes the geometry, `object-fit` changes the painting. **Wrap it.** Putting the image in a wrapper element moves the stretch onto the wrapper; the image inside is no longer a flex item and keeps its intrinsic sizing. This is a common pattern when the image also needs a caption or an overlay, but reaching for it purely to avoid stretch is heavier than `align-self`. ## The mirror-image pitfall: squashing The opposite complaint — "my logo got narrower when the nav filled up" — has a different cause on the main axis: flex items shrink by default when the line overflows, and an image shrinks with everything else. There the answer is `flex-shrink: 0` on the image, not an alignment change. Being able to say which axis a symptom lives on is half the diagnosis: distortion in the cross direction is an alignment default, distortion in the main direction is free-space distribution. ## Diagnosing it Inspect the image and compare its used width and height against the file's intrinsic dimensions (devtools shows both, typically as "rendered size" versus "intrinsic size"). If the rendered height exactly matches the flex line's height, stretch is your culprit. A second tell: the distortion changes when you add or remove content from a *sibling*, because the line's cross size is set by the tallest item. ## Why the default is what it is `stretch` is the right default for the common case — panels and columns that should share a height so borders and backgrounds line up. Replaced elements with intrinsic aspect ratios are the exception, and CSS chose not to special-case them, so the correction is yours to write. Modern layouts often pair `align-self: flex-start` with `aspect-ratio` on the image box so the reserved space is stable before the file loads.
- If you keep the stretched box on purpose, how do you stop the picture itself from distorting?Use `object-fit`. `cover` scales the image uniformly to fill the box and crops the overflow; `contain` scales it uniformly to fit and leaves empty space. `object-position` controls which part survives the crop. Neither property resizes the box — the flex item stays stretched, only the painted content changes.
- Does the same stretch problem appear in a flex-direction: column container?Yes, and it is more noticeable. In a column container the cross axis is horizontal, so an image with `width: auto` stretches to the container's full width and is scaled up past its natural size. The fix is identical: `align-self: flex-start` on the image, or an explicit width.
- An image inside a full nav bar gets narrower rather than taller. Is that the same bug?No — that is main-axis shrinking, not cross-axis stretching. When the line overflows, every item shrinks in proportion, images included, so the logo compresses. Add `flex-shrink: 0` to the image. Naming which axis the distortion is on is the fastest way to pick the right fix.
saying these in an interview costs you the question
- Saying images are not flex items and cannot be affected
- Reaching for width: 100% or max-width to undo a cross-axis stretch
- Claiming object-fit prevents the box from being stretched
- Confusing main-axis shrinking with cross-axis stretching
- Believing an image's intrinsic aspect ratio always overrides layout