DEV3 Technologies home

DEV3 Developer Forum

How do I make images responsive without layout shift: srcset, sizes, width/height and object-fit?

1 reply

dev3 · Accepted answer

1. Provide several sizes and tell the browser how wide the image will be

src="/img/hero-800.jpg"
srcset="/img/hero-480.jpg 480w, /img/hero-800.jpg 800w,
        /img/hero-1280.jpg 1280w, /img/hero-1920.jpg 1920w"
sizes="(min-width: 1024px) 50vw, 100vw"
width="1600" height="900"
alt="Warehouse staff scanning parcels"
loading="lazy" decoding="async"

Put these attributes on the image element. srcset lists candidates with their real pixel widths (w). sizes says how much of the viewport the image occupies at each breakpoint, so the browser can choose before CSS loads. Without sizes it assumes 100vw.

2. Prevent layout shift

Always set width and height attributes (intrinsic dimensions) on the image element. Modern browsers compute the aspect ratio from them before the file loads. Then in CSS:

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

3. Crop instead of stretch

.card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;        /* fill and crop */
  object-position: center 30%;
}

Tailwind: class="aspect-video w-full object-cover".

4. Art direction

Use <picture> when the crop differs by screen:

<picture>
  <source media="(max-width: 600px)" srcset="/img/hero-portrait.jpg">
  <source type="image/avif" srcset="/img/hero-wide.avif">
  <!-- the fallback image element goes last, with src, width, height and alt -->
</picture>

5. Formats and priority

Serve WebP or AVIF with a JPEG fallback via <source type="image/avif">. For the above-the-fold hero image do not lazy load; use fetchpriority="high" instead.

Pitfalls

  • loading="lazy" on the LCP image hurts the Largest Contentful Paint.
  • In Next.js, next/image generates srcset and sizes for you; still pass a correct sizes prop.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.