How to Resize Images with CSS
Make images responsive without distortion, or fit them into a fixed box with cropping or empty space. Learn the CSS patterns and how to choose between them.
For an image that should shrink to fit its container while keeping its full content and original proportions, use:
img {
max-width: 100%;
height: auto;
}
max-width: 100% prevents the image from overflowing its parent, and height: auto lets the browser preserve its intrinsic aspect ratio. Choose a different pattern when the design calls for a fixed-size frame: object-fit: cover fills the frame by cropping, while object-fit: contain shows the whole image and may leave empty space.
1. Choose how the image should fit
Before setting dimensions, decide what the layout should do with the image:
| Goal | CSS approach | Result |
|---|---|---|
| Show the whole image, scale down to fit | max-width: 100%; height: auto; |
Preserves the image ratio and avoids overflow. It does not enlarge a smaller image. |
| Fill a fixed-ratio frame | object-fit: cover |
Preserves proportions, fills the frame, and crops any excess. |
| Show the whole image inside a fixed frame | object-fit: contain |
Preserves proportions; blank space can remain in the frame. |
| Stretch the image to fill the frame | object-fit: fill |
Fills the frame, but can distort the image. |
| Keep the image at its intrinsic size in the frame | object-fit: none |
Does not resize the image to fit the content box; parts may not fit. |
| Use the smaller of intrinsic size and contain sizing | object-fit: scale-down |
Shows the whole image without enlarging it. |
For ordinary responsive content, start with the first row. Use the fixed-frame options for thumbnails, cards, avatars, and galleries where consistent dimensions matter.
2. Make an image responsive without cropping
Apply the rule to a class when only some images need to be fluid:
.responsive-image {
display: block;
max-width: 100%;
height: auto;
}
<img
class="responsive-image"
src="landscape.jpg"
width="1600"
height="900"
alt="A mountain landscape at sunrise"
>
The CSS lets the rendered image become narrower than its natural width when its parent is narrower. The automatic height follows the width and preserves the source ratio. The intrinsic width and height attributes describe the source dimensions; they do not prevent CSS from scaling the rendered image.
The logical-property equivalent is:
.responsive-image {
max-inline-size: 100%;
block-size: auto;
}
Use max-width when you want broad familiarity and compatibility with existing CSS. Logical properties express the constraint in terms of the inline and block axes, which adapt to writing modes.
When to use width: 100%
width: 100%; height: auto; makes the image occupy the full available width, including when that means enlarging it beyond its natural dimensions. Use that only when upscaling is intended. To fill a container only up to the image’s natural width, use max-width: 100% instead.
/* Fill the parent's width, even if that enlarges the image */
.image-fill {
display: block;
width: 100%;
height: auto;
}
/* Shrink when needed, but do not enlarge */
.image-fluid {
display: block;
max-width: 100%;
height: auto;
}
If an image still overflows, inspect its parent and surrounding layout. A fixed width on the image, a minimum width on a flex or grid child, or a parent that itself overflows can defeat the expected layout. Check which element is wider than the viewport in browser developer tools.
3. Fit an image into a fixed-ratio box
For a thumbnail that should fill a landscape frame consistently, set the frame’s preferred ratio and choose how its contents fit:
.thumbnail {
display: block;
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
object-position: center;
}
aspect-ratio gives the box a preferred shape. At least one dimension must be automatic for that preferred ratio to affect sizing. object-fit controls how the image content is drawn inside the element’s content box; it prevents the chosen frame shape from forcing the image pixels to stretch.
With cover, the browser scales the image until the box is covered, then clips the overflow. With contain, it scales the whole image until it fits, leaving unused space if the image and frame ratios differ:
.thumbnail--whole-image {
display: block;
width: 100%;
aspect-ratio: 16 / 9;
object-fit: contain;
background: #eee;
}
The background makes the unused area visible as a deliberate part of the design. If the image itself should not be enlarged, use scale-down rather than contain.
Control where a crop falls
object-position determines which part of the image stays visible when cover crops it. Its default is centered; use a different position when the subject is near an edge:
.thumbnail--subject-at-top {
object-fit: cover;
object-position: top center;
}
.thumbnail--subject-at-right {
object-fit: cover;
object-position: 80% center;
}
Try the crop at the narrowest and widest frame sizes. A position that works in one layout may cut off an important subject at another.
4. Keep space reserved while the image loads
Include meaningful intrinsic dimensions when they are known:
<img src="product.jpg" width="1200" height="800" alt="A red ceramic mug">
The browser can use those dimensions to determine the aspect ratio before the image finishes loading. This helps it establish the image’s space early and reduces layout movement as the content arrives. Responsive CSS can still scale the displayed image:
img {
max-width: 100%;
height: auto;
}
For a deliberately cropped frame, keep the image’s intrinsic dimensions accurate and set the frame ratio in CSS. The source ratio and the display frame ratio describe different things: the former describes the file; the latter describes the layout.
5. Complete responsive gallery example
This example uses fluid columns and fixed-ratio thumbnails. The images shrink with their grid cells, crop consistently, and keep their subjects near the center:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive image gallery</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
padding: 1rem;
font-family: system-ui, sans-serif;
}
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
gap: 1rem;
}
.gallery img {
display: block;
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
object-position: center;
border-radius: 0.5rem;
}
</style>
</head>
<body>
<main class="gallery">
<img src="coast.jpg" width="1600" height="900" alt="Coastline seen from above">
<img src="forest.jpg" width="1200" height="900" alt="Sunlight between forest trees">
<img src="city.jpg" width="1600" height="1000" alt="City skyline at dusk">
</main>
</body>
</html>
The grid sets a minimum column size while allowing columns to wrap. Each image fills its cell and is cropped to a 16:9 frame. For an uncropped gallery, remove the frame ratio and use height: auto; max-width: 100%;.
6. Troubleshoot common sizing problems
| Symptom | Likely cause | Fix |
|---|---|---|
| The image overflows its container | A fixed image width, a wide parent, or a flex/grid child refusing to shrink. | Remove conflicting fixed widths, add max-width: 100%, and inspect parent sizing. In a flex or grid item, try min-width: 0 on the item if its minimum content size is blocking shrinkage. |
| The image looks stretched | Both width and height are set to conflicting values, or object-fit: fill is in effect. |
For uncropped scaling, make one dimension automatic. For a fixed frame, use cover or contain. |
| The image is unexpectedly cropped | object-fit: cover fills the frame by clipping excess. |
Switch to contain to show the whole image, or change the frame ratio or object-position. |
| Blank bands appear around the image | contain preserves the whole image inside a differently shaped box. |
Accept the bands and style the box background, or use cover if cropping is acceptable. |
| A small image becomes blurry | width: 100% enlarges it beyond its natural pixel dimensions. |
Use max-width: 100% to avoid enlarging, or provide a higher-resolution source for the intended display size. |
| Content jumps when the image loads | The browser did not know the image ratio early enough to reserve its space. | Provide accurate HTML width and height attributes; use a CSS aspect-ratio for a fixed-ratio frame. |
| The crop hides the subject | The default centered crop excludes content near an edge. | Set object-position, such as top center or 80% center, and check at multiple frame sizes. |
7. Performance and practical notes
- CSS changes display size, not file size. A large source image still has to be downloaded even when it is displayed as a small thumbnail. Use appropriately sized image assets when download weight matters.
- Avoid needless enlargement. Enlarging a small source can look soft.
max-width: 100%allows shrinkage without forcing enlargement. - Reserve layout space. Accurate intrinsic dimensions help the browser determine the ratio before load. For cropped components, an explicit frame ratio keeps the layout shape consistent.
- Choose crops for the content. A uniform frame is useful for a grid, but the same crop may not suit every image. Adjust
object-positionwhere the subject requires it. - Do not stretch photographs to fix a layout. Stretching changes visible proportions. Correct the frame sizing or select a deliberate crop instead.
8. Or skip the browser setup
If you need a screenshot of a page to review how its images fit at a given viewport, you can capture the page directly with ScreenshotNeo. Its website screenshot API returns an image or PDF from one GET request, and the same parameter names used by other screenshot APIs also work. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed, and response headers report the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
9. FAQ
Should I use width or max-width for a responsive image?
Use max-width: 100% when the image should shrink to fit but not grow past its natural width. Use width: 100% when it should fill the container even if that enlarges it.
Does object-fit resize an image?
It controls how replaced content such as an image is drawn within its element’s content box. The element’s box still needs dimensions or a sizing rule that gives it a shape to fit.
How do I show the whole image in a fixed-size box?
Set the box dimensions or ratio and use object-fit: contain. The full image remains visible, though empty space can remain in the box.
How do I make every thumbnail the same shape?
Give each image a shared frame ratio with aspect-ratio and use object-fit: cover for edge-to-edge thumbnails. Adjust object-position for images whose subjects are off-center.


