TechEarl

Why Your Responsive Images Look Squished (max-width and height: auto)

Responsive images look squished when you pin both a width and a height in CSS. The fix is max-width: 100% with height: auto so the image scales proportionally, plus the width/height HTML attributes for layout stability.

Ishan Karunaratne⏱️ 8 min readUpdated
Share thisCopied
Stop responsive images from looking squished with max-width 100% and height auto, keep the width and height HTML attributes for CLS, and use aspect-ratio and object-fit for fixed boxes.

Responsive images look squished when both width and height are fixed in CSS; the fix is max-width: 100% with height: auto so the image scales proportionally. If your responsive images look squished or stretched, you almost certainly set both a width and a height in CSS. An image has an intrinsic aspect ratio, and the moment you pin both dimensions to fixed values that do not match that ratio, the browser distorts the picture to obey you. The fix is one rule:

css
img {
  max-width: 100%;
  height: auto;
}

max-width: 100% stops the image from overflowing its container (it shrinks to fit on small screens but never blows up past its natural size), and height: auto tells the browser to compute the height from the width so the aspect ratio is preserved. That is the whole job for the common case. The rest of this page is why it goes wrong, why you still want the HTML width and height attributes, and what to do when you genuinely need a fixed box.

Why the squish happens

The distortion comes from over-specifying. Any of these will do it:

css
/* Both fixed, ratio ignored: stretched */
img { width: 400px; height: 300px; }

/* Fluid width, fixed height: squished as the column narrows */
img { width: 100%; height: 200px; }

In the first rule you forced a 4:3 box onto, say, a 16:9 photo, so the browser squashes the photo to fit. In the second, the width tracks the container while the height stays nailed at 200px, so the image gets more and more distorted as the viewport shrinks. A replaced element like <img> only keeps its proportions when at most one of its two dimensions is fixed and the other is left to follow.

So the rule is simple: set one dimension, let the other be auto. With responsive layouts the width is the one that flexes, so width (or max-width) is what you control and height: auto is what you hand back to the browser.

Keep the width and height HTML attributes anyway

Here is the part people get wrong: because they are setting height: auto in CSS, they assume they should strip the width and height attributes off the <img> tag. Do not. Those two things solve different problems and cooperate cleanly.

html
<img src="photo.jpg" width="1600" height="900" alt="...">

The width and height attributes are the image's intrinsic size. The browser divides them to get the aspect ratio and reserves a correctly-shaped box before the file downloads. Without them, a width: 100%; height: auto image collapses to zero height until it loads, then shoves the page down when it arrives, which is exactly the layout shift that Cumulative Layout Shift (CLS) measures and Core Web Vitals penalises.

The CSS height: auto does not fight the attributes. The browser uses the attribute ratio to size the placeholder, then the responsive CSS scales the displayed image while holding that same ratio. Attributes for layout reservation, CSS for fluid display. You want both.

aspect-ratio: the modern reinforcement

If the markup cannot carry width/height attributes (a background-ish hero, a CMS that strips them, an element that is not an <img> at all), the aspect-ratio property reserves the box from CSS instead:

css
img {
  max-width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}

aspect-ratio: 16 / 9 tells the browser the shape ahead of time, so it can reserve space the same way the HTML attributes do. It is Baseline across current browsers, so you can lean on it in production. When the <img> already has matching width/height attributes, you do not need this too. It is the fallback for the cases where the attributes are not available.

When you DO need a fixed box: object-fit

Sometimes a fixed box is the design: a grid of thumbnails that must all be the same square, an avatar, a card header that has to be exactly 320 by 180 regardless of the source photo. There you do set both dimensions, and you stop the distortion with object-fit instead of height: auto:

css
.thumb {
  width: 320px;
  height: 180px;
  object-fit: cover;
}

object-fit controls how the image fills the box you forced on it, without stretching:

  • cover scales the image to fill the whole box and crops whatever overflows. Best for thumbnails and hero crops where edge loss is acceptable.
  • contain scales it to fit entirely inside the box, leaving letterbox or pillarbox bars. Best when the whole image must stay visible (logos, product shots).
  • fill is the default, and it is the one that stretches. That is the behaviour you are escaping.

Pair it with object-position to choose which part survives the crop (object-position: center top keeps faces in frame). object-fit is Baseline and safe to use everywhere. The mental model: height: auto keeps the box matching the image; object-fit keeps the image matching the box.

Inside grid and flex containers

One more squish source worth naming: an <img> placed directly as a flex item can stretch along the cross axis because flex containers stretch items by default. If a sidebar image looks oddly tall, that is usually it. Keep the max-width: 100%; height: auto rule and let the image sit in a block wrapper, or set align-self: start on the item so the flex container stops stretching it.

For the wider picture of srcset, sizes, and serving the right file to each screen, see responsive images done properly. When the box dimensions come from a calculation rather than a literal value, CSS calc() is how you express them. And if you are styling images conditionally based on whether a wrapper has a caption or a particular class, the :has() parent selector makes that selection possible without JavaScript.

FAQ

You set both a fixed width and a fixed height in CSS (or width: 100% with a fixed height), and the ratio of that box does not match the image's natural ratio, so the browser distorts the image to fit. Set only one dimension and let the other be auto.

It tells the browser to calculate the height from whatever width the image ends up at, so the intrinsic aspect ratio is preserved. Combined with max-width: 100%, the image shrinks to fit narrow screens without ever stretching or overflowing.

Yes. The HTML width and height attributes give the browser the intrinsic ratio so it reserves a correctly-shaped box before the image loads, preventing layout shift (CLS). The CSS height: auto handles fluid display on top of that. They do not conflict; you want both.

Use aspect-ratio when the element cannot carry intrinsic width/height attributes (a non-img element, or markup a CMS strips). It reserves the box shape from CSS the same way the attributes would. If the img already has matching attributes, you do not need it as well.

Set both dimensions and add object-fit: cover (fills the box, crops the overflow) or object-fit: contain (fits inside, adds letterbox bars). The default, fill, is the one that stretches. Use object-position to control which part stays in frame when cropping.

See also

Sources

Authoritative references this article was fact-checked against.

TagsCSSresponsive imagesheight automax-widthaspect-ratioobject-fitCLS

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Software Systems Architect · Senior Software Engineer · Engineering Leadership

Software systems architect and senior software engineer with more than two decades designing, building, and running production software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Now a CTO, though what I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts

Ship responsive images with native HTML: srcset width descriptors plus sizes for resolution switching, picture with media for art direction, and source type for AVIF and WebP fallback.

Responsive Images: srcset, sizes, and the picture Element

Ship responsive images with native HTML: srcset width descriptors plus sizes for resolution switching, picture with media for art direction, and source type for AVIF/WebP fallback. Plus the sizes gotcha that quietly defeats the whole thing.

Clean responsive images from ACF Image fields. ID + wp_get_attachment_image for auto srcset, manual srcset control, picture element for art direction.

Proper Responsive Images with ACF Image Fields

The cleanest pattern for responsive images from an ACF Image field: ID return format plus wp_get_attachment_image, which produces a complete srcset and sizes attribute from registered image sizes. Plus the manual srcset pattern when you need control.