We are still cooking the magic in the way!
Images, Figures & Responsive Images
Adding Images to Your Page
Images are a fundamental part of the web. The <img> element is a self-closing tag that embeds an image into your page. It requires two essential attributes: src (the path or URL to the image file) and alt (alternative text that describes the image). The alt attribute is not optional -- it is critical for accessibility, SEO, and situations where the image fails to load.
Example: Basic Image Element
<img src="images/sunset.jpg" alt="A golden sunset over the ocean with orange and purple clouds">
<!-- Image from an external URL -->
<img src="https://example.com/photos/mountain.jpg" alt="Snow-capped mountain peak against a clear blue sky">Notice that the alt text is descriptive and specific. Instead of writing "sunset picture," describe what the image actually shows. Screen readers read this text aloud to visually impaired users, so quality alt text makes a real difference.
Image Formats: Choosing the Right One
Not all image formats serve the same purpose. Choosing the correct format affects your page load speed, visual quality, and user experience. Here are the formats every web developer should know:
JPEG (JPG) is best for photographs and images with many colors. It uses lossy compression, meaning some quality is lost to reduce file size. PNG supports transparency and is ideal for logos, icons, and images with sharp edges or text. It uses lossless compression, so quality is preserved but files are larger. GIF supports simple animations and is limited to 256 colors, making it unsuitable for photographs. SVG is a vector format that scales to any size without losing quality, perfect for icons, logos, and illustrations. WebP is a modern format developed by Google that provides superior compression for both lossy and lossless images, often producing files 25-35% smaller than JPEG or PNG with similar quality.
<picture> element for older browsers that do not support WebP.Setting Width and Height to Prevent Layout Shift
When a browser loads your page, it initially does not know the dimensions of your images. As each image loads, the page content shifts to make room, creating an annoying visual jump known as Cumulative Layout Shift (CLS). This hurts user experience and your Core Web Vitals score. The fix is simple: always specify width and height attributes on your images.
Example: Preventing CLS with Width and Height
<!-- Always specify dimensions to reserve space -->
<img src="product.jpg" alt="Red wireless headphones" width="800" height="600">
<!-- Make it responsive with CSS -->
<style>
img {
max-width: 100%;
height: auto;
}
</style>The width and height attributes tell the browser the aspect ratio of the image so it can reserve the correct space before the image downloads. The CSS max-width: 100% and height: auto ensure the image still scales responsively within its container.
width and height attributes on images. This forces the browser to reflow the page layout every time an image finishes loading, causing content to jump around. Users find this extremely frustrating, especially on slower connections, and Google penalizes pages with high layout shift in search rankings.The figure and figcaption Elements
When an image needs a caption or represents a self-contained piece of content referenced from the main text, wrap it in a <figure> element. The <figcaption> element inside provides a visible caption that is semantically linked to the image. This is better than placing a paragraph below an image, because assistive technologies understand that the caption describes the figure.
Example: Image with Figure and Caption
<figure>
<img src="chart-q3-sales.png" alt="Bar chart showing Q3 sales increasing from $40k in July to $65k in September" width="700" height="400">
<figcaption>Figure 1: Q3 sales performance by month, showing a 62% increase from July to September.</figcaption>
</figure>The <figure> element is not limited to images. It can also wrap code snippets, diagrams, quotes, or any content that is referenced as a unit. The <figcaption> can appear as either the first or last child inside the figure.
Responsive Images with srcset and sizes
Different devices have different screen sizes and resolutions. Serving a massive 2000-pixel-wide image to a mobile phone wastes bandwidth and slows the page. The srcset attribute lets you provide multiple versions of the same image at different widths, and the sizes attribute tells the browser how wide the image will be displayed at various viewport sizes. The browser then picks the most appropriate image automatically.
Example: Responsive Images with srcset and sizes
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px"
alt="Developer working at a standing desk with dual monitors"
width="1600"
height="900">The srcset attribute lists each image file and its actual width in pixels using the w descriptor. The sizes attribute uses media conditions to tell the browser: on screens up to 600px wide, the image fills the full viewport width; on screens up to 1200px, it fills half the viewport; and on larger screens, it displays at 800px. The browser combines this information with the device pixel ratio to select the optimal file.
The picture Element for Art Direction
While srcset lets the browser choose between different sizes of the same image, the <picture> element gives you full control over which image to show at different breakpoints. This is called art direction -- you might want to show a wide landscape photo on desktop but a cropped close-up on mobile.
Example: Art Direction with the picture Element
<picture>
<source media="(min-width: 1024px)" srcset="banner-wide.webp" type="image/webp">
<source media="(min-width: 1024px)" srcset="banner-wide.jpg" type="image/jpeg">
<source media="(min-width: 640px)" srcset="banner-medium.webp" type="image/webp">
<source media="(min-width: 640px)" srcset="banner-medium.jpg" type="image/jpeg">
<source srcset="banner-mobile.webp" type="image/webp">
<img src="banner-mobile.jpg" alt="Team collaborating around a whiteboard in a modern office" width="1200" height="600">
</picture>The browser evaluates each <source> element from top to bottom and uses the first one whose media query and type are supported. The <img> element at the end serves as the fallback for browsers that do not support the <picture> element. This pattern also lets you serve WebP to supported browsers with a JPEG fallback.
Lazy Loading Images
Pages with many images can be slow to load if every image is fetched immediately. The loading="lazy" attribute tells the browser to defer loading an image until it is about to enter the viewport. This dramatically improves initial page load time, especially on image-heavy pages like galleries and e-commerce listings.
loading="lazy" to images that are visible in the initial viewport (above the fold), such as hero banners or logos. Lazy loading those images actually hurts performance because the browser delays loading content that the user sees first. Only apply lazy loading to images further down the page.Alt Text Best Practices
Writing effective alt text is both an accessibility requirement and a skill. Good alt text describes the content and function of the image concisely. For informative images, describe what the image shows in one or two sentences. For functional images like buttons or links, describe the action rather than the appearance. For decorative images that add no information, such as visual dividers or background patterns, use an empty alt attribute (alt="") to tell screen readers to skip them entirely.
Avoid starting alt text with "image of" or "picture of" because screen readers already announce the element as an image. Never leave the alt attribute missing entirely, as screen readers will then read the file name, which is confusing and unhelpful.
Practice Exercise
Create a photo gallery page with at least four images. Use the <figure> and <figcaption> elements for each image. Include width and height attributes on every image to prevent layout shift. Add loading="lazy" to all images except the first one. For one image, use the <picture> element to provide a WebP version with a JPEG fallback. Write descriptive alt text for each image, and include one decorative image with an empty alt="" attribute. Finally, add CSS to make all images responsive using max-width: 100% and height: auto.