Responsive Images

What are responsive images?
Responsive images is the term used to describe the new trend of serving appropriate images to a web page based on the size of the screen and the type of device being used.
Why do I need them?
The biggest benefit is reducing unnecessary downloading in order to speed up pages and save bandwidth on mobile use. They can also be used to serve higher resolution images to retina/high density pixel displays (like iPhones and retina MacBooks), and then just normal resolution images to standard screen devices.
How do they work then?
Well, the browser doesn’t actually know how big an image is until it’s downloaded, but it does know how big the screen is and the pixel density. Basically, you write in the html which images you have and some information about them, and it does some quick maths to figure out which is the most appropriate one and downloads it – clever eh?
There are 2 similar but slightly different approaches you can take: either using <img> tags with the “srcset” and “sizes” attributes or using the <picture> element.
<img>, srcset and sizes
This method adds 2 new attributes to the <img> html tag. The “srcset” attribute tells the browser the filenames of the different versions of the image and how big they are in pixels. The “sizes” attribute tells the browser how big the image is going to be displayed relative to the size of the window.
Example 1:
  srcset="medium.jpg 1000w,
          large.jpg 2000w"

The example above has 2 images in the srcset; these are a medium.jpg, which is 1000px wide (1000w), and a large.jpg which is 200px wide (2000w). The “sizes” attribute is telling the browser that this image will be shown at the full width of the browser, 100vw (viewport width).
If the browser window is smaller than 1000px wide (most phones and tablets), the browser will download the medium.jpg image, saving time and bandwidth. The “src” attribute is the fallback for browsers that do not support this feature.
Example 2:
  srcset="icon.png 1x,
          icon.png-@2x.png, 2x"

This example includes 2 files. The “1x” and “2x” after the filename describes the intended pixel density that this image is to be used at. Therefore, “icon.png-@2x.png” will have twice the width in pixels of “icon.png”, but will be displayed at the same size.
If the browser has the larger image cached it will use that version, so this method is best used to switch out different size versions of the same image.
The <picture> element
The <picture> element is a lot more versatile, and will always show the image that meets the defined parameters (whereas <img>, “srcset” and “sizes” will use cached versions where possible). You can also include media queries alongside each file and this gives you a lot more control over the image that is being displayed. For example, you could use an image with a completely different aspect ratio on a phone in portrait mode. It also contains <source> elements; each one defines a file (or files) and the criteria in which to use it.
  <source src="examples/images/large.jpg" media="(min-width: 1200px)">
  <source src="examples/images/medium.jpg" media="(min-width: 600px)">
  <source src="examples/images/small.jpg alt="default image">
  <img src="examples/images/medium.jpg" alt=“fallback image">

This example explicitly states which image is to be used at different screen widths and again includes a fallback for unsupported browsers. Here, the “small.jpg” image will show up to a browser width of 600px, the “medium.jpg” will show up to 1200px and the “large.jpg will show above 1200px, regardless of what’s in the cache. You can also include “sizes”, “srcset” and the “w” and “x” values described above to create more complex and refined image queries.
Browser Support
<img> with “srcset” and “sizes” can be used now, and is supported by leading desktop browsers (latest Chrome and Firefox, “sizes” not supported in Safari and MSEdge) and will fall back to the ‘src’ attribute if unsupported.
<picture> has less support and you won’t be able to use it natively for a while yet. However, Picturefill ( is a javascript polyfill that can be used in the meantime, but it has some limitations.
Morphing devices (GIF)