Skip to main content
April 1, 2026Dan Rodney/12 min read

Responsive Images: Free HTML & CSS Tutorial

Master responsive images for faster loading websites

Two Responsive Image Techniques

Img Srcset

Same image across various screen sizes with optimal resolution. Mobile gets small files, desktop gets large sizes, and hi-res screens get appropriate images automatically.

Picture Element

Provides art direction control with different images, croppings, and aspect ratios. Vertical images for mobile, horizontal for desktop layouts.

Topics Covered in This HTML & CSS Tutorial:

Img Srcset, the Picture Element

Exercise Preview

preview responsive images

Exercise Overview

In this comprehensive exercise, you'll master responsive images—a critical skill for modern web development that directly impacts user experience and business metrics. By delivering optimized images tailored to each user's screen size and resolution, you'll dramatically improve page load times, reduce bandwidth consumption, and enhance user satisfaction across all devices.

The stakes are higher than ever: Google's Core Web Vitals now heavily weight page loading speed in search rankings, making image optimization a direct SEO factor. Users abandon sites that load slowly, with studies showing that even a 100ms delay can hurt conversion rates by 7%.

You'll master two essential techniques: the srcset attribute for img tags, and the more sophisticated picture element. Understanding when and how to use each approach is crucial for professional web development:

  • Img Srcset: Your go-to solution when you need the same image to adapt across various screen sizes and resolutions. This technique automatically serves small, optimized files to mobile users while delivering high-resolution assets to desktop users and retina displays. The browser intelligently selects the most appropriate image based on device capabilities and network conditions.

  • Picture Element: The advanced choice when you need complete "art direction" control over your images. Use this when different screen sizes require fundamentally different images—such as a vertical crop for mobile portraits versus a horizontal landscape for desktop displays. This element gives you pixel-perfect control over the visual narrative across devices.

Getting Started

Let's set up your development environment to explore these powerful responsive image techniques.

  1. Navigate to the Responsive Images folder located in Desktop > Class Files > Advanced HTML CSS Class. Open this entire folder in your preferred code editor (Visual Studio Code, Sublime Text, or similar) to access all exercise files efficiently.
  2. Open srcset.html from the Responsive Images folder to begin with the srcset technique.
  3. Preview srcset.html in Chrome—we'll leverage Chrome DevTools extensively for testing responsive behavior across different device conditions.

    You'll see a simple page with one image and accompanying text. This stripped-down approach lets you focus entirely on the responsive image implementation without distracting page elements.

  4. Keep this page open in Chrome throughout the exercise—you'll be switching between your code editor and browser frequently to test your implementations.

Setup Instructions

1

Open Project Files

Navigate to Desktop > Class Files > Advanced HTML CSS Class > Responsive Images folder and open in your code editor

2

Open Source File

Open srcset.html from the Responsive Images folder in your code editor

3

Preview in Chrome

Open srcset.html in Chrome browser as we'll be using Chrome DevTools for testing

Using Img Srcset for 1x & 2x (Retina) Graphics

Modern displays vary dramatically in pixel density. Standard displays use a 1:1 pixel ratio, while retina and high-DPI screens pack multiple physical pixels into each CSS pixel. The srcset attribute elegantly handles this complexity by letting you specify multiple image versions, allowing the browser to automatically select the optimal file for each user's display.

  1. Return to srcset.html in your code editor.
  2. Add the srcset attribute to specify both standard and high-resolution image versions:

    <img srcset="img/sunset-320.jpg 1x, img/sunset-640.jpg 2x" src="img/sunset-320.jpg" ALT="sunset">

    NOTE: HTML attribute order is flexible—srcset can appear before or after src. The src attribute serves as a crucial fallback for legacy browsers that don't support srcset. Check current browser support at caniuse.com/#search=srcset, though support is now virtually universal in 2026.

  3. Save the file and reload the page in Chrome. The results will vary based on your display:

    • Standard (1x) displays: You'll see an image labeled "320px" displayed at 320 pixels wide
    • Retina (2x) displays: You'll see an image labeled "640px" displayed at 320 pixels wide, providing crisp, high-resolution rendering
    • Legacy browsers: Automatically fall back to the src image (320px), ensuring universal compatibility

    This automatic selection represents one of the web platform's most elegant features—intelligent resource delivery with zero JavaScript required.

  4. Let's verify this behavior across different display types using Chrome's powerful DevTools. Ctrl-click (Mac) or Right-click (Windows) anywhere on the page and select Inspect to open Chrome DevTools.

    Since browsers cache downloaded images for performance, we need to disable caching during our testing phase to see real-time switching behavior.

  5. Click the gear icon (Settings) in the top-right corner of DevTools.
  6. Scroll to the Network section and check Disable cache (while DevTools is open). This ensures fresh image downloads during testing.
  7. Close settings by clicking the X button.
  8. Click the Toggle device toolbar button devtools device mode icon to enter device simulation mode.
  9. Select iPhone 6/7/8 from the device dropdown menu.
  10. Reload the page using Cmd-R (Mac) or Ctrl-R (Windows).
  11. Since this simulates a 2x device, you should see the 640px high-resolution image.
  12. To test 1x display behavior, we need to adjust the device pixel ratio. If this option isn't visible, click the three-dot menu chrome devtools menu and select Add device pixel ratio.

    add device pixel ratio responsive images

  13. You'll see DPR: 2.0 to the right of the dimensions. Switch the device dropdown to Responsive to unlock the DPR controls.
  14. Click the DPR dropdown and select 1 to simulate a standard display.
  15. Reload the page—you should now see the 320px standard-resolution image.
  16. Reset the DPR to Default: 2.0 to return to high-resolution simulation.
  17. Click the Toggle device toolbar button devtools device mode icon to exit device mode.
  18. Keep DevTools open for the next section.

Browser Compatibility Note

The src attribute serves as fallback for older browsers that don't understand srcset. Check caniuse.com for current browser support statistics.

Using Img Srcset with Sizes

The 1x/2x approach works well for resolution-based switching, but modern responsive design demands more sophisticated image delivery. The sizes attribute combined with width-based srcset gives browsers comprehensive information about available images and their intended display sizes, enabling optimal selection based on viewport size, image dimensions, screen resolution, and even network conditions.

This approach is particularly powerful because it lets browsers make intelligent decisions about image loading before the page layout is calculated, significantly improving performance.

  1. Return to srcset.html in your code editor.
  2. Comment out the previous example to keep it for reference:

    <!-- <h1>1x vs. 2x</h1>
    <img srcset="img/sunset-320.jpg 1x, img/sunset-640.jpg 2x" src="img/sunset-320.jpg" ALT="sunset"> -->
  3. Add a new section to demonstrate the sizes technique:

    <h1>Sizes</h1>
    <img src="img/sunset-1280.jpg" ALT="sunset">
  4. Add empty srcset and sizes attributes as placeholders:

    <img src="img/sunset-1280.jpg" ALT="sunset" srcset="" sizes="">
  5. Format the attributes on separate lines for better readability—a best practice for complex responsive image markup:

    <img src="img/sunset-1280.jpg" ALT="sunset" 
         srcset="" 
         sizes="">
  6. Populate the srcset with all available image sizes and their actual pixel widths:

    <img src="img/sunset-1280.jpg" ALT="sunset" 
         srcset="img/sunset-320.jpg 320w, 
                 img/sunset-640.jpg 640w, 
                 img/sunset-1280.jpg 1280w, 
                 img/sunset-2560.jpg 2560w" 
         sizes="">

    NOTE: The "w" descriptor stands for width and tells the browser each image's actual pixel dimensions. This crucial information enables the browser to calculate pixel density and select appropriate images without downloading files first—a significant performance optimization.

  7. Add the sizes attribute to define how large the image will appear at different viewport widths:

    <img src="img/sunset-1280.jpg" ALT="sunset" 
         srcset="img/sunset-320.jpg 320w, 
                 img/sunset-640.jpg 640w, 
                 img/sunset-1280.jpg 1280w, 
                 img/sunset-2560.jpg 2560w" 
         sizes="(min-width: 800px) 50vw, 
               (min-width: 640px) 75vw, 
               100vw">
  8. Understanding the sizes attribute is crucial for professional implementation. This attribute tells the browser how much space the image will occupy in the final page layout, relative to the viewport width. The browser uses this information to select the optimal image file before rendering begins.

    Why can't browsers calculate this automatically? The browser must decide which image to download during the initial HTML parsing phase, before CSS is processed and layout is calculated. This early decision-making dramatically improves performance by parallelizing image downloads with other rendering processes. Learn more about this optimization at tinyurl.com/dev-onri

    The sizes syntax uses media queries followed by length values. You can use absolute units (px, em) or viewport-relative units (vw for viewport width), and even CSS calc() functions. Percentages are not supported. The browser processes conditions from left to right, using the first match. The final value (100vw) serves as the default when no conditions match.

  9. Save the file and reload the page in Chrome.
  10. Maximize your browser window to see the wide-viewport behavior.
  11. If DevTools isn't docked to the right, click the chrome devtools menu menu and select Dock to right:

    chrome dock to right

  12. Resize the DevTools panel to narrow the viewport to approximately 320px. The current viewport width appears in the top-right corner as you resize.
  13. Reload the page to trigger fresh image selection.
  14. You should see the 320px image on 1x displays or the 640px image on 2x displays—the browser automatically factors in pixel density.
  15. Gradually widen the DevTools panel and reload at different widths to observe automatic image switching as breakpoints are crossed.
  16. Notice that when narrowing the viewport, images don't automatically downgrade to smaller versions.

    This behavior is intentional and beneficial: once a high-quality image is cached, there's no visual or performance benefit to downloading a smaller version. Users get the best possible image quality while avoiding unnecessary network requests.

  17. Set the viewport to approximately 600px width.
  18. Reload to see targeted image selection: 640px images on 1x displays, 1280px images on 2x displays.
  19. Close DevTools while keeping the page open for the next section.

Adding Srcset with Sizes

1

Comment Out Previous Code

Comment out the 1x vs 2x heading and img tag to work with the new sizes example

2

Add Image Sources

Define srcset with multiple image widths (320w, 640w, 1280w, 2560w) where 'w' indicates pixel width

3

Define Sizes Attribute

Set media conditions with viewport-relative sizes: (min-width: 800px) 50vw, (min-width: 640px) 75vw, 100vw

Why Browser Needs Size Information

The browser must decide which file to download before rendering the page. This speeds up asset downloading and page rendering, which is why we provide size information upfront.

Using the Picture Element for 1x & 2x (Retina) Graphics

While srcset excels at serving different sizes of the same image, the picture element provides complete control over which images appear at different viewport sizes. This "art direction" capability is essential when you need different crops, compositions, or even entirely different images across devices. Think portrait-oriented product shots for mobile and landscape shots for desktop, or detailed wide shots for large screens with simplified versions for small screens.

  1. Switch to a new file to explore the picture element. Open picture.html from the Responsive Images folder.
  2. This file starts empty, giving you a clean slate. Add a complete picture element within the body tags:

    <picture>
       <source media="(min-width: 1280px)" srcset="img/model-desktop-1280.jpg">
       <source media="(min-width: 768px)" srcset="img/model-tablet-768.jpg">
       <img src="img/model-mobile-375.jpg" ALT="Model">
    </picture>

    NOTE: The picture element processes sources in order, using the first media query match. If no source matches, the img element serves as the fallback. Unlike srcset, the picture element gives you complete control—the browser must use your specified conditions rather than making its own optimization decisions. This directive approach is perfect when design requirements override performance optimizations.

  3. Preview picture.html in Chrome.
  4. Resize your browser window from narrow to wide and observe three distinctly different images appearing: Mobile 375px, Tablet 768px, and Desktop 1280px. Each image features different aspect ratios, crops, and compositions—demonstrating true art direction across breakpoints.

    Currently, you're seeing 1x images regardless of your display's pixel density. Let's enhance this to serve appropriate resolution versions automatically.

  5. Return to picture.html in your code editor.
  6. Restructure the code with better formatting to accommodate additional complexity:

    <picture>
       <source media="(min-width: 1280px)" 
               srcset="img/model-desktop-1280.jpg">
       <source media="(min-width: 768px)" 
               srcset="img/model-tablet-768.jpg">
       <img src="img/model-mobile-375.jpg" ALT="Model">
    </picture>
  7. Enhance each source element with both 1x and 2x image options:

    <picture>
       <source media="(min-width: 1280px)" 
               srcset="img/model-desktop-1280.jpg 1x, 
                       img/model-desktop-2560.jpg 2x">
       <source media="(min-width: 768px)" 
               srcset="img/model-tablet-768.jpg 1x, 
                       img/model-tablet-1536.jpg 2x">
       <img src="img/model-mobile-375.jpg" ALT="Model">
    </picture>
  8. Add srcset to the fallback img element for complete responsive coverage:

    <img src="img/model-mobile-375.jpg" ALT="Model" srcset="">
  9. Complete the mobile srcset with 1x and 2x options:

    <picture>
       <source media="(min-width: 1280px)" 
               srcset="img/model-desktop-1280.jpg 1x, 
                       img/model-desktop-2560.jpg 2x">
       <source media="(min-width: 768px)" 
               srcset="img/model-tablet-768.jpg 1x, 
                       img/model-tablet-1536.jpg 2x">
       <img src="img/model-mobile-375.jpg" ALT="Model" 
            srcset="img/model-mobile-375.jpg 1x, 
                    img/model-mobile-750.jpg 2x">
    </picture>

    The img element now serves double duty: it's both the fallback for older browsers and the active source for viewports smaller than 768px, complete with resolution switching.

  10. Save and reload the page in Chrome.
  11. Resize from narrow to wide—you'll now see appropriate resolution versions: 1x images (375px, 768px, 1280px) on standard displays or 2x images (750px, 1536px, 2560px) on retina displays.
  12. Let's verify the resolution switching using DevTools. Right-click the page and select Inspect.
  13. Activate device simulation with the Toggle device toolbar button devtools device mode icon.
  14. Select iPhone 6/7/8 from the device menu.
  15. Reload the page—you should see the Mobile 750px image (2x version for retina display).
  16. Switch to Responsive mode in the device dropdown.
  17. Change DPR to 1 to simulate a standard display.
  18. Reload—you should now see Mobile 375px (1x version). If the viewport is too wide, narrow it and refresh.
  19. Reset DPR to Default: 2.0.
  20. Exit device mode by clicking the Toggle device toolbar button devtools device mode icon.
  21. Close DevTools, keeping the page open for the final section.

Picture Element vs Img Srcset

FeaturePicture ElementImg Srcset
Browser ControlDeveloper dictates which sourceBrowser has discretion to choose
Image VariationDifferent croppings/aspect ratiosSame image, different resolutions
Use CaseArt direction neededOptimization only
Recommended: Use Picture Element when you need different images for different screen sizes, not just different resolutions.

Using the Picture Element with Sizes

The picture element becomes even more powerful when combined with the sizes attribute. While our previous implementation only considered screen resolution, adding sizes allows the browser to factor in the actual display size of images within your layout. This creates a sophisticated optimization system that considers viewport width, image display size, pixel density, and network conditions.

  1. Return to picture.html in your code editor.
  2. Add sizes attributes to each source element to specify how much viewport space the image will occupy:

    <picture>
       <source media="(min-width: 1280px)"
               sizes="50vw"
               srcset="img/model-desktop-1280.jpg 1x, 
                       img/model-desktop-2560.jpg 2x">
       <source media="(min-width: 768px)" 
               sizes="75vw"
               srcset="img/model-tablet-768.jpg 1x, 
                       img/model-tablet-1536.jpg 2x">
       <img src="img/model-mobile-375.jpg" ALT="Model" 
            sizes="100vw"
            srcset="img/model-mobile-375.jpg 1x, 
                    img/model-mobile-750.jpg 2x">
    </picture>
  3. Convert from resolution-based (1x/2x) to width-based descriptors for more granular control:

    <picture>
       <source media="(min-width: 1280px)" 
               sizes="50vw"
               srcset="img/model-desktop-1280.jpg 1280w, 
                       img/model-desktop-2560.jpg 2560w">
       <source media="(min-width: 768px)" 
               sizes="75vw"
               srcset="img/model-tablet-768.jpg 768w, 
                       img/model-tablet-1536.jpg 1536w">
       <img src="img/model-mobile-375.jpg" ALT="Model" 
            sizes="100vw"
            srcset="img/model-mobile-375.jpg 375w, 
                    img/model-mobile-750.jpg 750w">
    </picture>

    This advanced configuration gives browsers comprehensive information to make optimal decisions based on multiple factors:

    • Desktop (1280px+): Images occupy 50% of viewport width—browser selects between 1280w and 2560w images
    • Tablet (768px-1279px): Images fill 75% of viewport—browser chooses between 768w and 1536w options
    • Mobile (<768px): Images span full viewport width—browser picks between 375w and 750w versions

    The browser combines this sizing information with actual viewport dimensions, pixel density, and potentially network speed to deliver the most appropriate image for each user's specific context.

Save your file and test the final implementation. You now have complete control over responsive image delivery, combining art direction with intelligent optimization—a professional-grade solution that ensures every user receives the perfect image for their device and network conditions.

This comprehensive approach to responsive images represents modern web development best practices, balancing visual design requirements with performance optimization and user experience across the full spectrum of devices and network conditions your users encounter in 2026.

Picture Element Breakpoint Flow

Small screens

Mobile (767px and smaller)

model-mobile-375.jpg or model-mobile-750.jpg displays at 100vw width

Medium screens

Tablet (768px to 1279px)

model-tablet-768.jpg or model-tablet-1536.jpg displays at 75vw width

Large screens

Desktop (1280px and above)

model-desktop-1280.jpg or model-desktop-2560.jpg displays at 50vw width

Key Takeaways

1Responsive images improve page loading speed, leading to better user experience and higher Google page rankings
2Img srcset attribute automatically serves optimal image resolution based on screen density and viewport size
3Picture element provides art direction control, allowing different image crops and compositions across breakpoints
4The 'w' descriptor in srcset indicates image width in pixels, helping browsers choose appropriate files
5Sizes attribute tells browsers how large images will be in the final layout using viewport units or CSS calc
6Picture element sources are evaluated top-to-bottom, with browsers using the first matching media condition
7Always include src attribute as fallback for browsers that don't support srcset or picture elements
8Use img srcset for most cases; reserve picture element only when different image compositions are needed across screen sizes

RELATED ARTICLES