← All articles 8 min read

How to Make an Image Smaller in HTML (5 Methods)

You have a 4000x3000 image. You need it to display at 800x600. There are two completely different problems hiding in that sentence:

  1. Display size — how large the image appears on the page (controlled by HTML and CSS)
  2. File size — how many bytes the browser downloads (controlled by compression and export settings)

Setting width="800" on an <img> tag makes the image look smaller. The browser still downloads all 4.8 MB of the original. Your page still loads slowly. Your Core Web Vitals still suffer.

This guide covers both problems. Methods 1-4 handle display size. Method 5 handles file size. For a fast site, you need both.

Quick Comparison

Method Controls Responsive? Reduces File Size? Best For
width/height attributes Display size No No Fixed-dimension layouts, CLS prevention
CSS max-width Display size Yes No Fluid layouts, responsive design
srcset + sizes Display size + source selection Yes Yes (serves smaller files) Serving resolution-appropriate images
<picture> element Display size + format + art direction Yes Yes (serves smaller files/formats) Format switching, art direction
Pre-upload compression File size N/A Yes Reducing actual bytes transferred

Method 1: width and height Attributes

The simplest approach. Add width and height directly to the <img> tag:

<img
  src="hero-photo.jpg"
  alt="Mountain landscape at sunset"
  width="800"
  height="600"
>

The browser renders the image at 800x600 pixels regardless of the original file dimensions. These values are in CSS pixels, not the intrinsic pixel dimensions of the file.

Why you should always include both attributes: When width and height are present, the browser reserves the correct space in the layout before the image loads. This prevents Cumulative Layout Shift (CLS) — that annoying jump when images pop in and push content around. For a deeper look at how dimensions affect performance, see our guide on HTML image dimensions.

The catch: The browser still downloads the full-size file. A 4000x3000 JPEG at 4.8 MB renders at 800x600, but the user waited for 4.8 MB to arrive. On mobile connections, that matters a lot.

When to use this method:

Method 2: CSS max-width and height

CSS gives you responsive control that HTML attributes alone cannot:

<img
  src="hero-photo.jpg"
  alt="Mountain landscape at sunset"
  width="1200"
  height="900"
  style="max-width: 100%; height: auto;"
>

Or in a stylesheet (preferred):

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

This is the responsive image baseline. The image scales down to fit its container but never stretches beyond its intrinsic width. height: auto preserves the aspect ratio.

A more controlled approach with object-fit:

.thumbnail {
  width: 300px;
  height: 300px;
  object-fit: cover;  /* crops to fill the box */
}

.preview {
  width: 300px;
  height: 200px;
  object-fit: contain; /* fits inside the box, may letterbox */
}

object-fit: cover is your friend for avatar circles, card thumbnails, and gallery grids — any context where you need a fixed aspect ratio box but have images of varying proportions.

Keep the HTML attributes: Even when CSS controls the visual size, include width and height on the <img> tag. The browser uses them to calculate the aspect ratio for layout reservation. CSS controls appearance; HTML attributes prevent layout shift.

The same catch applies: The browser still downloads the full-size file. You are resizing on the client side. For optimal website image sizes, you want to serve appropriately-sized source files — which brings us to srcset.

Method 3: srcset and sizes for Responsive Images

srcset lets you provide multiple versions of the same image at different resolutions. The browser picks the best one based on viewport width and screen density:

<img
  src="hero-800w.jpg"
  srcset="
    hero-400w.jpg   400w,
    hero-800w.jpg   800w,
    hero-1200w.jpg 1200w,
    hero-1600w.jpg 1600w
  "
  sizes="
    (max-width: 600px) 100vw,
    (max-width: 1200px) 50vw,
    800px
  "
  alt="Mountain landscape at sunset"
  width="1200"
  height="900"
>

Here is what each piece does:

The browser does the math: on a 375px-wide phone at 2x density, it needs a 750px-wide image, so it picks hero-800w.jpg. On a 1440px desktop at 1x, it needs 800px, same file. On a 1440px Retina display, it grabs hero-1600w.jpg.

The real benefit: A phone downloads a 45 KB file instead of a 380 KB file. Same visual quality, 88% less data. This is the first method that actually reduces bytes transferred.

The work involved: You need to generate multiple versions of each image. Tools like Pixotter's resize tool handle this — drop your image, export at 400, 800, 1200, and 1600px widths, done.

For more on how srcset interacts with lazy loading, check our dedicated guide.

Method 4: The picture Element

<picture> goes beyond srcset by adding art direction and format switching:

<picture>
  <!-- Serve AVIF where supported (smallest file) -->
  <source
    type="image/avif"
    srcset="hero-800w.avif 800w, hero-1200w.avif 1200w"
    sizes="(max-width: 800px) 100vw, 800px"
  >
  <!-- Fall back to WebP -->
  <source
    type="image/webp"
    srcset="hero-800w.webp 800w, hero-1200w.webp 1200w"
    sizes="(max-width: 800px) 100vw, 800px"
  >
  <!-- Fall back to JPEG for old browsers -->
  <img
    src="hero-800w.jpg"
    srcset="hero-800w.jpg 800w, hero-1200w.jpg 1200w"
    sizes="(max-width: 800px) 100vw, 800px"
    alt="Mountain landscape at sunset"
    width="1200"
    height="900"
    loading="lazy"
    decoding="async"
  >
</picture>

The browser picks the first <source> it supports, then selects the right size from that source's srcset. If nothing matches, it falls back to the <img> tag.

Art direction example — serve a different crop on mobile versus desktop:

<picture>
  <source
    media="(max-width: 600px)"
    srcset="hero-mobile-crop.jpg"
  >
  <source
    media="(max-width: 1200px)"
    srcset="hero-tablet.jpg"
  >
  <img
    src="hero-desktop.jpg"
    alt="Mountain landscape at sunset"
    width="1200"
    height="600"
  >
</picture>

On mobile, you might want a tighter crop that shows the subject clearly instead of a tiny version of the full landscape. Art direction gives you that control.

When <picture> beats srcset alone:

Method 5: Actually Reduce the File Size

Methods 1-4 control how the browser displays the image. None of them change the source file. If your original JPEG is 4.8 MB, that is still 4.8 MB hitting the network (unless srcset or <picture> routes the browser to a smaller variant you prepared).

The most impactful optimization is shipping a smaller file in the first place:

  1. Resize to the dimensions you need. A 4000x3000 photo displayed at 800x600 wastes 96% of its pixels. Export at 1600x1200 (2x for Retina) and the file drops from 4.8 MB to under 800 KB before any compression.
  2. Compress. JPEG quality 80 is visually indistinguishable from quality 100 for most photos, at 60-70% less file size. Tools like Pixotter's compress tool let you dial in a target size.
  3. Choose the right format. AVIF is 30-50% smaller than JPEG at equivalent quality. WebP splits the difference. PNG is for graphics with transparency and sharp edges, not photographs.

For a detailed walkthrough on shrinking file sizes, see our guide on how to make an image MB smaller.

Display Size vs. File Size — Why Both Matter

Think of it this way: HTML and CSS are the frame on the wall. The file is the painting. You can put a small frame around a huge painting — visitors still carried the huge painting into the room.

Here is the performance math:

Scenario File Downloaded Display Size LCP Impact
4000x3000 JPEG, no HTML sizing 4.8 MB Native (huge) Terrible
4000x3000 JPEG, width="800" 4.8 MB 800x600 Still terrible — same download
800x600 JPEG, width="800" 120 KB 800x600 Good
800x600 WebP, width="800" 65 KB 800x600 Great
srcset with 4 sizes, WebP 25-120 KB (varies) Responsive Best — right file for each device

The bottom row is the target: combine srcset (or <picture>) with properly sized, compressed source files. Each device downloads only the bytes it needs.

This is especially critical for Largest Contentful Paint (LCP). If your hero image is the LCP element — and it usually is — every kilobyte of unnecessary data delays your most important Core Web Vital. For a full rundown, see our image SEO optimization guide.

Frequently Asked Questions

Does setting width and height in HTML compress the image?

No. width and height attributes only control the display size — how many CSS pixels the image occupies on the page. The browser downloads the full original file regardless. To reduce the actual data transferred, resize and compress the source file before uploading.

What is the difference between width/height attributes and CSS width/height?

HTML attributes set the intrinsic size hint. The browser uses them to reserve space in the layout and prevent layout shift. CSS properties control the rendered size and can be responsive (percentages, max-width, media queries). Use both: HTML attributes for layout stability, CSS for responsive behavior.

Should I use srcset or the picture element?

Use srcset + sizes when serving the same image at different resolutions (the common case). Use <picture> when you need format switching (AVIF/WebP/JPEG fallback) or art direction (different crops per breakpoint). <picture> is a superset — it does everything srcset does and more, at the cost of more markup.

How do I make an image responsive without distortion?

Set max-width: 100% and height: auto in CSS. Include the correct width and height attributes on the <img> tag so the browser calculates the aspect ratio. The image will scale down with its container without stretching or squishing.

Is it bad to use inline styles for image sizing?

For one-off adjustments, inline styles are fine. For consistent patterns (thumbnails, hero images, card grids), move styles to a CSS class. The performance difference is negligible — the concern is maintainability. When you need to change every thumbnail from 200px to 250px, a class makes that one edit instead of fifty.

What image dimensions should I use for the web?

It depends on how the image is displayed. A full-width hero on a 1920px-wide layout needs a source file of at least 1920px (or 3840px for Retina). A 300px-wide thumbnail needs only 600px at most. The rule: export at 2x the CSS display size to look sharp on high-DPI screens, then let srcset serve 1x files to standard screens. For platform-specific sizes, check our website image size guide.

Wrapping Up

Making an image smaller in HTML is really two jobs: controlling how it renders and controlling how much data it costs. The HTML and CSS methods (attributes, max-width, srcset, <picture>) handle rendering. Compression and resizing handle file size.

For the fastest pages, do both. Resize and compress your images to the dimensions each breakpoint actually needs, then use srcset or <picture> to serve the right version to each device. Your visitors get sharp images. Your server sends fewer bytes. Everybody wins.