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⏱️ 7 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.

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

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

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

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.

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.