Responsive images in HTML and CSS
Summary
Implement responsive images using HTML and CSS techniques that adapt to different screen sizes, resolutions, and layout contexts. Serve optimized images for each user's device and viewing conditions.
Introduction #
Responsive images adapt to different screen sizes, resolutions, and layout contexts. You use them to serve optimized images for each user’s device and viewing conditions. This approach improves performance by avoiding unnecessary data transfer and enhances user experience by providing appropriate image quality.
Modern web standards provide multiple methods for implementing responsive images in Hypertext Markup Language (HTML) and Cascading Style Sheets (CSS). You choose techniques based on whether you need resolution switching, art direction, or component-level responsiveness.
The following selection methods for images exist in HTML and CSS:
| Scope | Image Selection Method | Use Case |
|---|---|---|
| HTML | Device-pixel-ratio-based selection | • Uses srcset with x descriptors• For content images • For fixed-size images |
| HTML | Viewport-based selection | • Uses srcset with w + sizes• For content images • For responsive images |
| HTML | Art direction-based selection | • Uses <picture> with <source media>• For content images • Changes crops/compositions |
| HTML | Device-pixel-ratio and art-direction-based selection | • Combines <picture> and srcset with xdescriptors• For content images • Handles both DPI changes and compositional changes |
| CSS | Media query-based selection | • Uses @media queries with different background-image URLs• For decorative images • For responsive images with different crops |
| CSS | Image-set-based selection | • Uses image-set() function with DPI descriptors• For decorative images • For both fixed-size and responsive images |
| CSS | Container query-based selection | • Uses @container queries with different image sources• For both content and decorative images • Element-based responsive images that adapt to container size |
Responsive images in HTML #
Responsive images in HTML are a method for providing the user agent with multiple image sources for an image slot. The user agent selects an image, depending on display density, size of the image element in the page, or any number of other factors.
Device-pixel-ratio-based selection #
Resolution switching for displaying an image with a fixed size while supporting different screen resolutions.
The img element’s sizes and srcset attributes are used in conjunction with the x descriptor.
Use this selection method if the rendered size of the image is fixed (e.g. by height and width attributes on the img element. The images in srcset only vary in their intrinsic width to support different resolutions (image content is identical). This allows for sharp images on high resolution screens.
Example 1 #
<img
alt="Example"
src="320.svg"
srcset="480.svg 1.5x,
640.svg 2x"
height="200"
width="200"
>
This HTML code creates a fixed-size image that serves different high-resolution versions to users with high-density displays.
The height="200" and width="200" attributes create a fixed 200x200 pixel container that the image will always occupy, regardless of which source file is loaded.
The srcset attribute provides alternative images for different pixel densities, where x stands for pixel density descriptor - specifically referring to the device pixel ratio (DPR) between CSS pixels and physical pixels.
The browser uses this information to select the optimal image: it will serve 320.svg to standard 1x displays, 480.svg to 1.5x density screens, and 640.svg to 2x (high resolution) displays. This ensures that users with high-resolution screens get a sharper, more detailed image that takes advantage of their extra pixels, while users with standard screens do not waste bandwidth downloading unnecessarily large files.
Progressive enhancement / fallback: User agents which do not support sizes and srcset attributes will ignore them and load the image referenced in the src attribute.
Viewport-based selection #
Resolution switching for displaying different sizes of an image.
The img element’s sizes and srcset attributes are used in conjunction with the w descriptor.
The images only vary in their size (image content is identical).
Example 1 #
<img
alt="Example"
sizes="100vw"
srcset="320.svg 320w,
480.svg 480w,
1024.svg 800w,
1440.svg 1000w"
src="320.svg">
This HTML code creates a responsive image that adapts to deliver the optimal file based on the user’s device. The sizes="100vw" attribute tells the browser that the image will always display at 100% of the viewport width, where vw stands for viewport width - a CSS unit where 1vw equals 1% of the browser window’s width.
The srcset attribute provides the browser with a menu of image options, where w stands for width descriptor and indicates the intrinsic width in pixels of each image file (320px, 480px, 800px, and 1000px).
Using this information, the browser calculates exactly how many pixels the image needs to fill on the screen and selects the smallest file that meets or exceeds that requirement. This selection process ensures mobile users get fast-loading smaller files while desktop users with large screens receive higher-resolution images.
Progressive enhancement / fallback: User agents which do not support sizes and srcset attributes will ignore them and load the image referenced in the src attribute.
Example 2 #
<img
alt="Example"
sizes="(max-width: 480px) 100vw, 800px"
srcset="320.svg 320w,
480.svg 480w,
1024.svg 800w"
src="320.svg">
This HTML code creates a responsive image that serves different optimized files based on both viewport size and screen density. The sizes attribute uses a media query (max-width: 480px) 100vw, 800px to tell the browser that on screens up to 480px wide, the image should display at 100% of the viewport width, while on larger screens it will display at a fixed 800px width.
The srcset provides multiple image options with w standing for width descriptor, indicating the intrinsic width in pixels of each source file (320px, 480px, and 800px).
The browser combines this information to calculate exactly which image file best matches the required display size while considering the user’s device pixel density. For example, on a 400px wide viewport with a 2x (high resolution) display, the browser would need an 800px image (400px × 2) and would select 1024.svg since it’s the smallest file that meets or exceeds this requirement.
This selection ensures optimal image quality without wasting bandwidth by delivering oversized files.
Progressive enhancement / fallback: User agents which do not support sizes and srcset attributes will ignore them and load the image referenced in the src attribute.
Art direction-based selection #
Resolution switching for displaying different image sizes and image contents.
The picture elements source element’s media and srcset attributes reference different image sources for the user agent to choose from.
The images may not only vary in their size but also image content may not be identical.
Example #
<picture>
<source
media="(max-width: 25rem)"
srcset="320.svg">
<source
media="(max-width: 50rem)"
srcset="480.svg">
<source
media="(min-width: 50rem)"
srcset="640.svg">
<img
src="640.svg"
alt="Example">
</picture>
The rendered size (height and width) of the image varies depending on which of the 3 resources is chosen. Use CSS to inform the user agent which about image dimensions, allows for faster rendering by eliminating the need for unnecessary repaints.
img {
width: 300px;
height: 300px;
}
@media (min-width: 50rem) {
img {
height: 300px;
width: 300px;
}
}
@media (max-width: 50rem) {
img {
height: 200px;
width: 200px;
}
}
@media (max-width: 25rem) {
img {
height: 100px;
width: 100px;
}
}
This picture has different heights and widths and consists of 3 different images. Three different breakpoints are applied:
- Breakpoint 1: Narrow
Viewport width <25rem), image width is100px*. - Breakpoint 2: Medium
Viewport width <50rem), image width is200px*. - Breakpoint 3: Wide
Viewport width >50remimage width is300px*.
*px refers to CSS pixels.
Progressive enhancement / fallback: User agents which do not support sizes and srcset attributes will ignore them and load the image referenced in the src attribute.
Device-pixel-ratio and art-direction-based selection #
Resolution switching for displaying different image sizes and contents.
Combination of two selection methods. It uses the source and img element’s srcset attribute with the x descriptor. The images in srcset vary in their intrinsic width to support different resolutions. This allows for sharp images on high resolution screens.
Example #
<picture>
<source
media="(max-width: 50rem)"
srcset="320.svg,
480.svg 1.5x,
640.svg 2x">
<img
alt="Example"
src="1024.svg"
srcset="1536.svg 1.5x,
2560.svg 2x">
</picture>
This code serves completely different image sets based on viewport size. For screens up to 50rem wide, it delivers mobile-optimized images (320.svg, 480.svg, 640.svg), while for larger screens it serves desktop-optimized images (1024.svg, 1536.svg, 2560.svg).
Progressive enhancement / fallback: User agents which do not support sizes and srcset attributes will ignore them and load the image referenced in the src attribute.
Responsive images in CSS #
Responsive images in CSS are a method for providing the the user agent with multiple image sources for an image slot. In some cases, the user agent selects an image, depending on display density, size of the image element in the page, or any number of other factors.
Media query-based selection #
Resolution switching for displaying different image sizes and contents.
Responsive images with the help of media queries (@media). The user agent picks the image that matches the media query. The user agent cannot chose from a set of sources to support different screen resolutions.
The images may not only vary in their size but also image content may not be identical.
Example #
/* Narrow screen*/
@media only screen and (max-width: 32rem) {
.background {
background-image: url("480.svg");
background-size: cover;
height: 300px;
width: 300px;
}
}
/* Medium screen*/
@media only screen and (min-width: 32rem) and (max-width: 42rem) {
.background {
background-image: url("1024.svg");
background-size: cover;
height: 400px;
width: 400px;
}
}
/* Wide screen*/
@media only screen and (min-width: 42rem) {
.background {
background-image: url("1200.svg");
background-size: cover;
height: 500px;
width: 500px;
}
}
This CSS code creates a responsive background image that changes based on screen width. For narrow screens under 32rem, it displays a small image (480.svg) in a 300px square container. On medium screens between 32rem and 42rem, it switches to a medium image (1024.svg) in a 400px container. For wide screens over 42rem, it uses a large image (1200.svg) in a 500px container, adapting both the image source and layout across different viewport sizes.
Progressive enhancement / fallback: User agents which do not support @media will ignore the rules.
Image-set-based selection #
Resolution switching for displaying an image with a fixed size while supporting different screen resolutions.
Responsive images with the help of the CSS function notation (image-set()). The user agent picks the image that matches the media query and screen resolution.
Example #
.background {
/* Progressive enhancement approach */
background: red;
background-image: fallback.img
background-image: image-set(
"320.svg" 1x,
"480.svg" 1.5x,
"680.svg" 2x
);
background-size: cover;
height: 300px;
width: 300px;
}
This code creates a fixed-size 300×300px element with a background image that adapts to different screen densities. It uses progressive enhancement by providing a red color fallback and a standard image for browsers that do not support image-set().
Modern browsers will select the appropriate image (320.svg, 480.svg, or 680.svg) based on the device’s pixel density (1x, 1.5x, or 2x), while older browsers will display the fallback image or red background instead.
Progressive enhancement / fallback: User agents which do not support image-set() will ignore the rules or use the fallback image.
Container query-based selection #
Element-based responsive images that adapt to container size rather than viewport size.
Responsive images using CSS container queries (@container) allow images to adapt based on their container’s dimensions instead of the overall viewport. This enables component-level responsiveness where images change based on their available space within layouts like cards, grids, or sidebars.
Example #
.card {
container-type: inline-size;
background: #f0f0f0;
padding: 1rem;
margin: 1rem 0;
border-radius: 8px;
}
.card img {
width: 100%;
height: auto;
display: block;
margin: 0 auto;
}
/* Small container: square image */
@container (max-width: 300px) {
.card img {
content: url("320.svg");
width: 200px;
height: 200px;
}
}
/* Medium container: medium image */
@container (min-width: 301px) and (max-width: 500px) {
.card img {
content: url("480.svg");
width: 300px;
height: 300px;
}
}
/* Large container: large image */
@container (min-width: 501px) {
.card img {
content: url("640.svg");
width: 400px;
height: 400px;
}
}
This code creates container-responsive images that adapt based on their card container’s width rather than the browser window. Cards are defined as containers with container-type: inline-size, allowing their child images to respond to the card’s own width.
When a card is narrow (under 300px), it displays a small 200px image (320.svg); at medium widths (301px-500px), it switches to a 300px medium image (480.svg); and for wide cards (501px+), it shows a large 400px image (640.svg). This enables true component-level responsiveness where each card’s image optimizes itself based on its available space.
Progressive enhancement / fallback: User agents which do not support @container queries will use the default image and layout.
Choosing the right method #
Select responsive image techniques based on your specific use case and requirements. Consider these factors when making your decision.
For content images that are needed to understanding the page, use HTML-based methods. The srcset and sizes attributes work well for resolution switching of the same image. The <picture> element provides art direction capabilities for different image compositions.
For decorative images that are part of the design, use CSS-based methods. Media queries offer control over both image source and styling at different breakpoints. The image-set() function provides pixel density switching for background images.
For component-based layouts, consider container queries. They allow images to adapt based on their container’s size rather than the global viewport. This approach works well with design systems and reusable components.
Always provide appropriate fallbacks for browsers that do not support your chosen method. Use progressive enhancement to ensure all users receive a functional experience regardless of their browser’s capabilities.
Terminologies #
- Art direction
Images in thesrcsetshow different images suitable for different space allocations. - CSS pixel
A measurement unit. CSS pixels are hardware pixels divided by pixel density. Also software pixel. - Device pixel ratio (DPR)
Ratio between hardware pixels and logical pixels. - Hardware pixel
An individual dot of light in the display. Also Physical pixel. - Intrinsic width
The actual size of an image. - Physical pixel
Same as Hardware pixel. - Pixel density
The number of pixels present per inch on a display. The density is measured in Pixels Per Inch (PPI). - Resolution switching
All images in thesrcsetshow the same thing but contain different numbers of pixels. - Software pixel
Same as CSS pixel. - User agent
Software that acts on behalf of a user, e.g. Web browser.
FAQ's #
Most common questions and brief, easy-to-understand answers on the topic:
What is the difference between srcset with w descriptors and x descriptors?
w descriptors describe the image's intrinsic width for viewport-based selection, while x descriptors indicate pixel density for fixed-size images on different resolution displays.
When should you use the <picture> element instead of srcset?
Use <picture> when you need art direction (different crops or compositions) and srcset when you need resolution switching (same image at different sizes).
How does image-set() differ from media queries for responsive background images?
image-set() handles pixel density switching automatically, while media queries require manual breakpoints for both viewport size and image source changes.
What is the advantage of container queries over viewport-based responsive images?
Container queries allow images to adapt based on their container's size rather than the viewport, enabling component-level responsiveness within flexible layouts.
Further readings #
Sources and recommended, further resources on the topic:
- WHATWG: The figure element
- WHATWG: The figcaption element
- WHATWG: The picture element
- WHATWG: The img element
- WHATWG: Images
- W3C: CSS Images Module Level 4
- W3C: image-set() notation
- MDN Web Docs: Responsive images
- MDN Web Docs: Using media queries
- MDN Web Docs: CSS values and units
- Wikipedia: Pixel density
License
Responsive images in HTML and CSS by Jonas Jared Jacek is licensed under CC BY-SA 4.0.
This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. To give credit, provide a link back to the original source, the author, and the license e.g. like this:
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://www.ditig.com/responsive-images">Responsive images in HTML and CSS</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://www.j15k.com/">Jonas Jared Jacek</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="license noopener noreferrer">CC BY-SA 4.0</a>.</p>For more information see the Ditig legal page.