SKILL.md
Responsive Images
Status: Production Ready ✅
Last Updated: 2026-01-14
Standards: Web Performance Best Practices, Core Web Vitals
Quick Start
Basic Responsive Image
<img
src="/images/hero-800.jpg"
srcset="
/images/hero-400.jpg 400w,
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w,
/images/hero-1600.jpg 1600w
"
sizes="(max-width: 640px) 100vw,
(max-width: 1024px) 90vw,
1200px"
alt="Hero image description"
width="1200"
height="675"
loading="lazy"
/>
Hero Image (LCP)
<img
src="/images/hero-1200.jpg"
srcset="
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w,
/images/hero-1600.jpg 1600w
"
sizes="100vw"
alt="Hero image"
width="1600"
height="900"
loading="eager"
fetchpriority="high"
/>
Configuration
Recommended Image Sizes
Use Case
Widths to Generate
Sizes Attribute
Full-width hero
800w, 1200w, 1600w, 2400w
100vw
Content width
400w, 800w, 1200w
(max-width: 768px) 100vw, 800px
Grid cards (3-col)
300w, 600w, 900w
(max-width: 768px) 100vw, 33vw
Sidebar thumbnail
150w, 300w
150px
Lazy Loading Rules
Image Position
loading
fetchpriority
Why
Hero/LCP
eager
high
Optimize LCP, prioritize download
Above fold (not LCP)
eager
omit
Load normally
Below fold
lazy
omit
Defer until near viewport
Off-screen carousel
lazy
omit
Defer until interaction
Common Patterns
Full-Width Responsive Image
<img
src="/images/banner-1200.jpg"
srcset="
/images/banner-600.jpg 600w,
/images/banner-1200.jpg 1200w,
/images/banner-1800.jpg 1800w,
/images/banner-2400.jpg 2400w
"
sizes="100vw"
alt="Full width banner"
width="2400"
height="800"
loading="lazy"
class="w-full h-auto"
/>
Grid Card Image (3 columns)
<img
src="/images/card-600.jpg"
srcset="
/images/card-300.jpg 300w,
/images/card-600.jpg 600w,
/images/card-900.jpg 900w
"
sizes="(max-width: 768px) 100vw,
(max-width: 1024px) 50vw,
33vw"
alt="Card image"
width="900"
height="600"
loading="lazy"
class="w-full h-auto"
/>
Fixed Aspect Ratio Container
<div class="aspect-[16/9] overflow-hidden">
<img
src="/images/video-thumbnail-800.jpg"
srcset="
/images/video-thumbnail-400.jpg 400w,
/images/video-thumbnail-800.jpg 800w,
/images/video-thumbnail-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 800px"
alt="Video thumbnail"
width="800"
height="450"
loading="lazy"
class="w-full h-full object-cover"
/>
</div>
Modern Formats (WebP + AVIF)
<picture>
<source
srcset="
/images/hero-800.avif 800w,
/images/hero-1200.avif 1200w,
/images/hero-1600.avif 1600w
"
sizes="100vw"
type="image/avif"
/>
<source
srcset="
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w,
/images/hero-1600.webp 1600w
"
sizes="100vw"
type="image/webp"
/>
<img
src="/images/hero-1200.jpg"
srcset="
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w,
/images/hero-1600.jpg 1600w
"
sizes="100vw"
alt="Hero image"
width="1600"
height="900"
loading="eager"
fetchpriority="high"
/>
</picture>
Art Direction (Different Crops)
<picture>
<source
media="(max-width: 640px)"
srcset="
/images/product-portrait-400.jpg 400w,
/images/product-portrait-800.jpg 800w
"
sizes="100vw"
/>
<source
media="(min-width: 641px)"
srcset="
/images/product-landscape-800.jpg 800w,
/images/product-landscape-1200.jpg 1200w,
/images/product-landscape-1600.jpg 1600w
"
sizes="(max-width: 1024px) 90vw, 1200px"
/>
<img
src="/images/product-landscape-1200.jpg"
alt="Product image"
width="1200"
height="675"
loading="lazy"
/>
</picture>
Error Prevention
Always Include Width and Height
Problem: Layout shift when images load (poor CLS score)
<!-- ❌ WRONG - causes layout shift -->
<img src="/image.jpg" alt="Image" loading="lazy" />
<!-- ✅ CORRECT - browser reserves space -->
<img
src="/image.jpg"
alt="Image"
width="800"
height="600"
loading="lazy"
/>
Source: Web.dev - Optimize CLS
Don't Lazy Load LCP Images
Problem: Delayed LCP, poor Core Web Vitals score
<!-- ❌ WRONG - delays LCP -->
<img
src="/hero.jpg"
alt="Hero"
loading="lazy"
/>
<!-- ✅ CORRECT - prioritizes LCP -->
<img
src="/hero.jpg"
alt="Hero"
loading="eager"
fetchpriority="high"
/>
Source: Web.dev - Optimize LCP
Use Width Descriptors (w), Not Density (x)
Problem: Browser can't choose optimal image for viewport
<!-- ❌ WRONG - only considers DPR -->
<img
src="/image.jpg"
srcset="/image.jpg 1x, /image@2x.jpg 2x"
alt="Image"
/>
<!-- ✅ CORRECT - considers viewport + DPR -->
<img
src="/image-800.jpg"
srcset="
/image-400.jpg 400w,
/image-800.jpg 800w,
/image-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 800px"
alt="Image"
width="800"
height="600"
/>
Exception: Density descriptors are appropriate for fixed-size images like logos.
Always Include Alt Text
Problem: Fails accessibility, SEO, and screen readers
<!-- ❌ WRONG -->
<img src="/product.jpg" />
<!-- ✅ CORRECT - descriptive alt text -->
<img src="/product.jpg" alt="Red leather messenger bag with brass buckles" />
<!-- ✅ CORRECT - decorative images use empty alt -->
<img src="/decorative-line.svg" alt="" role="presentation" />
Aspect Ratio with object-fit
Problem: Image stretches or squashes when container size differs from image dimensions
<!-- ❌ WRONG - image distorts -->
<div class="w-full h-64">
<img src="/image.jpg" alt="Image" class="w-full h-full" />
</div>
<!-- ✅ CORRECT - maintains aspect ratio -->
<div class="w-full h-64">
<img
src="/image.jpg"
alt="Image"
class="w-full h-full object-cover"
/>
</div>
Quick Reference
Sizes Attribute Patterns
<!-- Full width -->
sizes="100vw"
<!-- Content width (max 800px) -->
sizes="(max-width: 768px) 100vw, 800px"
<!-- Sidebar (fixed 300px) -->
sizes="300px"
<!-- 2-column grid -->
sizes="(max-width: 768px) 100vw, 50vw"
<!-- 3-column grid -->
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
<!-- Responsive with max-width -->
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 90vw, 1200px"
Common Aspect Ratios
Ratio
CSS
Use Case
16:9
aspect-[16/9]
Video thumbnails, hero images
4:3
aspect-[4/3]
Standard photos
3:2
aspect-[3/2]
DSLR photos
1:1
aspect-square
Profile pictures, Instagram-style
21:9
aspect-[21/9]
Ultrawide banners
object-fit Values
Value
Behavior
Use Case
cover
Fill container, crop edges
Card images, backgrounds
contain
Fit inside, preserve all content
Logos, product photos
fill
Stretch to fill
Avoid unless necessary
scale-down
Smaller of contain or original size
Mixed content sizes
Format Comparison
Format
Quality
File Size
Browser Support
Use Case
JPEG
Good
Medium
100%
Photos, complex images
PNG
Lossless
Large
100%
Logos, transparency
WebP
Excellent
Small
97%+
Modern browsers, photos
AVIF
Excellent
Smallest
90%+
Cutting-edge, fallback required
Recommended Strategy: AVIF → WebP → JPEG fallback using <picture>
Resources
Token Efficiency: ~70% savings by preventing trial-and-error with srcset/sizes syntax
Errors Prevented: 6 common responsive image issues documented above