The quick diagnosis
If an image looks sharp on your computer but blurry after upload, do not start by changing DPI or exporting the same file at a random higher quality. First find out which copy visitors are actually seeing.
In real publishing work, blur after upload usually comes from one of these situations:
| Symptom after upload | Likely cause | What to check first | Practical fix |
|---|---|---|---|
| Soft on the live page, especially around text | The image is being upscaled | Rendered width vs natural width | Export a larger source from the original |
| Sharp on one monitor, soft on iPhone or MacBook | DPR mismatch | CSS width x window.devicePixelRatio |
Use a 2x source for important images |
| Looks wider, taller, or slightly smeared | CSS or editor stretching | CSS width, height, object-fit, crop | Preserve aspect ratio or recrop deliberately |
| Looked fine before publish, bad on live page | CMS/CDN resized or recompressed it | Delivered URL, generated variant, cache | Upload closer to the final slot and inspect the live variant |
| Edges have halos, gradients band, faces look waxy | Lossy compression artifacts | Export quality and file format | Raise quality or switch format |
| Screenshot text looks fuzzy | Wrong format for hard edges | JPG used for UI/text | Use PNG or lossless WebP |
| You changed 300 DPI to 72 DPI and nothing changed | DPI metadata confusion | Pixel width and height | Ignore DPI for web display |
The useful question is not "What quality should I export?" It is "How many source pixels does this exact layout need, and what does the platform do to the file after I upload it?"
Pixels, CSS pixels, and device pixels
A web image has at least three sizes:
- File pixels: the actual pixel dimensions in the image file, such as 1600 x 1000.
- CSS display size: the space the page gives the image, such as a 760 px wide content column.
- Device pixels: the physical pixels on the screen. A high-density phone or laptop may use 2 physical pixels for every CSS pixel.
That means a 760 CSS px blog image is not automatically sharp just because the file is 760 px wide. On a 2x display, the sharper source is usually around 1520 px wide. This is the same reason an old screenshot can look acceptable on one office monitor and soft on a phone.
web.dev's image performance guidance uses the same logic: an image displayed in a 500 x 500 slot is ideally 500 x 500 on a 1x screen, about 1000 x 1000 on a 2x screen, and potentially larger on a 3x screen. In practice, you do not need to chase 3x for every asset. For most websites, 2x is a sensible target for important photos and screenshots, while thumbnails can often be smaller.
Cause 1: the source image is smaller than the display slot
This is the most common blur problem. A website builder may show a card image at 420 CSS px wide on desktop. The same image may appear in a featured section at 900 CSS px wide. If you uploaded a 600 px source because it "looked fine in preview," the browser has to invent pixels for the larger slot.
Upscaling can look like softness, not obvious blockiness. Faces lose pores and eyelashes. Product labels lose edge contrast. Text in screenshots becomes gray and fuzzy instead of crisp.
Use this sizing formula:
minimum source width = largest rendered CSS width x target DPR
Examples:
| Published use | Largest rendered CSS width | Good source width to try |
|---|---|---|
| Blog body image | 760 px | 1500-1600 px |
| Product grid card | 360 px | 720-900 px |
| Product detail image | 900 px | 1800-2000 px |
| Full-width hero | 1200 px | 2000-2400 px |
| UI screenshot shown in docs | 720 px | 1440 px, or exact 2x capture |
| Profile/avatar display | 160 px | 320-512 px |
If the original file is already smaller than the target, resizing it bigger will make the dimensions pass a requirement, but it will not restore real detail. Go back to the camera original, design export, or higher-resolution screenshot when possible.
Cause 2: the image is fine at 1x but weak on high-density screens
Retina and HiDPI screens are unforgiving. A 700 px image in a 700 CSS px slot can look normal on an older 1x monitor and soft on a 2x phone. The file did not change. The screen did.
This is especially visible with:
- Product photos with small labels
- UI screenshots
- Charts and diagrams
- Headshots cropped tightly
- Logos saved as raster JPG or PNG
- Photos displayed inside carousel or gallery lightboxes
For content images, a 2x source is usually enough. If a WordPress article column is 760 px wide, export around 1500-1600 px. If a Shopify product detail image opens in a zoom view, use a larger source, often 1800-2400 px depending on the template.
MDN's responsive image docs also explain why srcset and sizes matter. If your page offers multiple image versions, the browser can choose a source based on viewport, layout slot, pixel density, zoom level, and other conditions. If those values are missing or wrong, the browser may pick a smaller file than you expected.
Cause 3: CSS or the editor is stretching the image
Sometimes the uploaded file is large enough, but the layout distorts it. This happens when an editor or theme sets a fixed width and height without preserving the image's aspect ratio.
Common examples:
- A 1200 x 800 photo is forced into a 1200 x 630 social-preview box.
- A square logo is stretched into a wide header slot.
- A vertical screenshot is cropped into a horizontal blog card.
- A WYSIWYG editor lets you drag image handles and writes odd width/height values.
- CSS stretches the image to the container width and a fixed height without a matching
object-fitchoice.
Stretching is not the same as compression blur, but readers experience it the same way: the image looks wrong after upload.
Check the published element, not the file on your desktop. In the browser, right-click the image, inspect it, and look at the computed width, computed height, and the real source URL. If the aspect ratio of the rendered box does not match the source, fix the crop or use object-fit: cover deliberately instead of letting the browser squeeze the image.
Cause 4: the CMS, social app, or CDN created a weaker copy
Most publishing systems do not serve your original upload directly in every context. They create variants: thumbnails, medium images, large images, mobile crops, WebP conversions, compressed social previews, and CDN URLs with width or quality parameters.
That can be useful for performance, but it also creates surprises:
- You upload a 2400 px hero, but the page template serves a 1200 px generated copy in a 1200 CSS px slot on a 2x display.
- You upload a clean PNG screenshot, but the platform converts it to a lossy JPEG.
- You upload a compressed JPG, then the platform compresses it again.
- You replace an image, but your browser or CDN cache still shows an older, softer version.
- You inspect the media library original, while visitors see a transformed CDN URL.
For WordPress, Shopify, Squarespace, Webflow, and many social tools, the key is to inspect the delivered image URL, not just the media library file. A URL containing parameters such as w=, width=, q=, quality=, resize=, or a size name like medium_large is a clue that you are looking at a generated variant.
Open the delivered image URL in a private window and compare it with the original export. If the live copy is much smaller, you need to upload a better source, adjust the image component settings, or change the variant the template requests.
Cause 5: lossy recompression is being mistaken for blur
JPEG, WebP, and AVIF can all be used in lossy mode. Lossy compression is useful, but if it is pushed too far, the image does not simply become smaller. It loses information.
The artifacts depend on the content:
| Content in the image | What over-compression looks like | Better approach |
|---|---|---|
| Skin and fabric | Waxy texture, smeared detail | Raise quality and avoid repeated JPEG export |
| Sky or gradients | Bands instead of smooth transitions | Try WebP/AVIF or raise quality |
| Small text | Gray halos and fuzzy strokes | Use PNG or lossless WebP |
| Product edges | Crawling color noise around outlines | Raise quality and avoid resizing twice |
| Dark photos | Blocky shadows | Use a larger file budget or modern format |
If a file has already been compressed once by your editor, then compressed again by the CMS, then converted by a CDN, the damage compounds. Re-export from the master image instead of downloading the live image and compressing it again.
Cause 6: the format does not match the image
Wrong-format blur is common with screenshots and graphics. A photo and a UI screenshot do not need the same format.
Use these defaults:
- Photos: JPG, WebP, or AVIF. WebP is a practical default for modern sites when accepted by your CMS.
- Screenshots with small text: PNG or lossless WebP. Avoid low-quality JPG for UI captures.
- Logos, icons, diagrams: SVG where possible. Raster logos become blurry when resized.
- Photos with transparency needs: WebP or PNG, depending on destination support.
- Documents/forms that reject modern formats: JPG or PNG, because acceptance matters more than tiny file size.
MDN's format guidance describes JPEG as a good lossy format for still images, PNG as better when precise reproduction or transparency is needed, SVG as ideal for scalable interface graphics, and WebP as a strong modern option. Google's WebP documentation also notes that WebP supports lossy, lossless, transparency, and animation, with broad support in major browsers.
Cause 7: you are comparing the wrong version
One small workflow mistake causes a lot of confusion: comparing your desktop original with a browser preview that is still cached, zoomed, or showing a different responsive source.
Before deciding a platform "ruined" the image, check these:
- Browser zoom is set to normal page zoom.
- You are looking at the published page, not the editor preview.
- Cache is disabled or you are using a private window.
- The mobile view is loading the same crop or the intended mobile crop.
- The image is not being lazy-loaded from a placeholder.
- You are comparing the delivered file, not the media library original.
For a responsive image, Chrome DevTools or Firefox DevTools can show which image file was actually downloaded. MDN's responsive image guide recommends using browser network tools to see which image was loaded. That is often faster than guessing.
The browser check that finds the problem
Here is a quick diagnostic you can run on the live page:
- Open the published page.
- Right-click the blurry image and choose Inspect.
- Select the actual
<img>element in DevTools. - In the Console, run:
const img = $0;
const rect = img.getBoundingClientRect();
({
renderedWidth: Math.round(rect.width),
renderedHeight: Math.round(rect.height),
naturalWidth: img.naturalWidth,
naturalHeight: img.naturalHeight,
dpr: window.devicePixelRatio,
expectedWidthFor2x: Math.round(rect.width * 2),
currentSrc: img.currentSrc || img.src
});
Read the result like this:
- If
naturalWidthis lower thanrenderedWidth, the image is definitely being upscaled. - If
naturalWidthis close torenderedWidthbut the device pixel ratio is 2, the image may be fine on 1x screens but soft on HiDPI screens. - If
currentSrcis not the file you uploaded, your platform is serving a transformed variant. - If dimensions look correct but the image has halos or banding, the problem is compression or format.
MDN's naturalWidth reference is useful here because it describes the natural width as the intrinsic, density-corrected width in CSS pixels. That is exactly the number you need when comparing a live <img> with its rendered box.
Export settings that usually work
These are starting points, not fixed laws. Final quality depends on the image, the encoder, and what the platform does after upload.
| Upload destination | Better starting export |
|---|---|
| Blog content image | 1500-1600 px wide, WebP 80-85 or JPG 85-90 |
| Large website hero | 2000-2400 px wide, WebP 82-88 or AVIF 50-70 with fallback |
| Product grid thumbnail | 720-1000 px wide, WebP 75-82 |
| Product detail zoom image | 1800-2400 px wide, WebP/JPG 85-92 |
| UI screenshot in documentation | Capture at 2x, export PNG or lossless WebP |
| Social preview image | Match platform aspect ratio, often 1200 x 630 or 1080 x 1080 |
| Email or form upload | Use the required pixel limit and JPG/PNG if modern formats are rejected |
When a platform publishes recommended dimensions, follow them first. Then test on the real page. A strong export can still look bad if the theme crops it, the CDN asks for a smaller variant, or the platform recompresses aggressively.
A PhotoTools workflow before uploading
Use this when you have a sharp original and want a clean web copy:
- Find the largest real display width. Inspect the published slot or check your template. Do not guess from the editor thumbnail.
- Multiply by 2 for important images. A 760 px blog column becomes a 1500-1600 px export. A 360 px product card becomes a 720-900 px export.
- Resize first. Use Resize to set exact pixels or a target long edge. PhotoTools uses browser image APIs to resize into a canvas, so you can make delivery copies from the original without changing the master file.
- Compress second. Use Compress to export JPG, WebP, or AVIF at a reasonable quality. Start around 80-88 for most JPG/WebP photos, higher for faces, labels, and product detail.
- Inspect the uploaded version. Open the live page, check
currentSrc, compare rendered size with natural size, and look at the image at the size visitors actually see.
PhotoTools' resize code uses createImageBitmap with high resize quality and exports through OffscreenCanvas.convertToBlob(). MDN documents those APIs as browser-native ways to resize and export image data, with format and quality options for supported encoders. The practical benefit is simple: make the right-sized copy first, then compress that copy instead of letting a platform do all the decisions for you.
What not to do
Avoid these fixes because they usually attack the wrong problem:
- Do not change DPI and expect a web image to sharpen. Check pixel dimensions instead.
- Do not upload the smallest file that barely passes visual review in your editor. The platform may compress it again.
- Do not stretch a small logo into a large header. Use SVG or a larger raster asset.
- Do not screenshot a non-retina screen and publish it at retina sizes. Capture at 2x or export from the design file.
- Do not repeatedly download and recompress the live image. Go back to the original source.
- Do not judge from the CMS editor alone. Editors often show different previews than the public page.
The bottom line
A blurry uploaded image is usually not mysterious. It is a mismatch somewhere in the chain: source pixels, display slot, device pixel ratio, CSS sizing, responsive image selection, platform processing, or compression.
The clean workflow is:
- Measure the real display slot.
- Export from the original at roughly 2x for important images.
- Use the right format for the content.
- Compress moderately, not aggressively.
- Inspect the live delivered image URL after upload.
Once you check those five things, the fix becomes specific. You will know whether to resize larger, adjust the layout, raise quality, change format, or stop worrying about DPI entirely.