HTML Tutorial menu

HTML Responsive Images

Responsive images look sharp and load fast on every screen, from a small phone to a large monitor.

The Problem

A 2000-pixel-wide photo looks great on a laptop. On a phone it is shown at 400 pixels, but the phone still downloads the whole big file. That wastes mobile data and makes the page slow.

Responsive images fix this: the browser picks the right file for each screen.

Fit the Screen with CSS

The first step is simple. Stop an image from becoming wider than its container:

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
  img { max-width: 100%; height: auto; }
</style>
</head>
<body>

<h2>Resize the window</h2>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='400'%3E%3Crect width='1200' height='400' fill='%23e34c26'/%3E%3Ctext x='600' y='220' font-size='60' text-anchor='middle' fill='white'%3E1200 x 400%3C/text%3E%3C/svg%3E" alt="A wide orange banner" width="1200" height="400">

</body>
</html>
Try it Yourself »

The image shrinks on small screens and never grows bigger than its real size. Keep width and height in the HTML so the browser saves the right space before the image loads.

srcset: Different Sizes of One Image

srcset lists the same picture in several widths. The w after each number is the real width of that file in pixels.

Example

html
<img src="shop-800.jpg"
     srcset="shop-400.jpg 400w, shop-800.jpg 800w, shop-1600.jpg 1600w"
     sizes="(max-width: 600px) 100vw, 50vw"
     alt="Inside Ali's computer shop"
     width="800" height="533">
PartMeaning
srcsetThe files you have and their widths
sizesHow wide the image will be shown: full screen width (100vw) on screens up to 600px, half the width (50vw) on larger screens
srcThe fallback for very old browsers

The browser does the maths. A phone 400 pixels wide picks shop-400.jpg (or shop-800.jpg if it has a sharp high-density screen). A desktop picks a bigger one.

srcset for Sharp Screens

For an image that is always shown at the same size, like a logo, list files by pixel density with x:

Example

html
<img src="logo.png" srcset="logo.png 1x, logo@2x.png 2x" alt="Workownix logo" width="150" height="50">

Phones with sharp "retina" screens take the 2x file. Others take the normal one.

The picture Element

<picture> gives you full control. It holds several <source> tags and one <img>. The browser uses the first source that matches, and the <img> is the fallback.

Use 1: Modern Formats

WebP and AVIF files are much smaller than JPEG at the same quality. Offer them first, and keep JPEG for older browsers:

Example

html
<picture>
  <source srcset="biryani.avif" type="image/avif">
  <source srcset="biryani.webp" type="image/webp">
  <img src="biryani.jpg" alt="A plate of chicken biryani" width="600" height="400">
</picture>

Use 2: A Different Picture for Small Screens

On a phone, a wide group photo becomes tiny. You can show a closer, cropped photo instead. This is called "art direction".

Example

html
<!DOCTYPE html>
<html>
<body>

<p>Make the window narrower than 600 pixels and watch the picture change.</p>

<picture>
  <source media="(max-width: 600px)"
    srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='300'%20height='300'%3E%3Crect%20width='300'%20height='300'%20fill='%232a7ae2'/%3E%3Ctext%20x='150'%20y='160'%20font-size='30'%20text-anchor='middle'%20fill='white'%3EPhone%3C/text%3E%3C/svg%3E">
  <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='300'%3E%3Crect width='800' height='300' fill='%23e34c26'/%3E%3Ctext x='400' y='160' font-size='40' text-anchor='middle' fill='white'%3EDesktop%3C/text%3E%3C/svg%3E"
    alt="Course banner" style="max-width:100%; height:auto;">
</picture>

</body>
</html>
Try it Yourself »

The alt text always goes on the <img> inside <picture>. The <source> tags never have alt.

Lazy Loading

Images far down the page do not need to load until the visitor scrolls to them. Add loading="lazy":

Example

html
<img src="gallery-12.jpg" alt="Students in the computer lab" loading="lazy" width="400" height="300">
ValueBehaviour
eagerLoad at once (the default)
lazyLoad when the image comes near the screen

Do not lazy-load the main image at the top of the page. It should appear as fast as possible. For that one, you can even add fetchpriority="high".

Quick Checklist

  1. Add max-width: 100%; height: auto; in your CSS.
  2. Always give width, height and alt.
  3. Use srcset and sizes for big photos.
  4. Use <picture> for WebP/AVIF or for a different crop on phones.
  5. Use loading="lazy" for images below the first screen.

Exercise

Exercise

Which attribute stops an image from downloading until the user scrolls near it?

Learn HTML with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp