Responsive images

# The img tag

  • src specifies a URL to download the image
  • but image size may not be correct for the device viewing it
    • for the same physical size, high density screens requires image with more pixels
    • conversely, bandwidth constrained devices may wish to use smaller images

# Browser pipeline

  • browsers are highly optimised; starts downloading HTML dependencies as early as possible
  • given a choice of multiple image sources, starts downloading them before CSS is even loaded

# Selection process

  • uses intrinsic knowledge of the viewport and device pixel ratio (DPR) to determine size of source image
  • selects the smallest source image that meets its needs
  • alternately, may select even smaller ones to optimise for bandwidth

# The sizes and srcset attributes

  • if unspecificed, default sizes attribute is 100vw
  • srcset is comma separated list of image sources and their native sizes
  • eg, a 400px @ DPR2 screen and a 800px @ DPR1 screen might select the same 800w version-b.jpg image
  • browsers that don't support this falls back to using the src attribute
<img
src="image.jpg"
sizes="100vw"
srcset="version-a.jpg 400w, version-b.jpg 800w, version-c.jpg 1200w" >

# Media conditions

  • but images not always full 100vw width
  • sizes can specify a comma separated list of media conditions; first matching one applies
  • eg, screens above 800px caps the image at 800px, but screens below it show a 400px version (subject to same DPR calculations from before)
  • recall that browsers make selection before CSS is loaded, so slight duplication of media conditions from CSS
<img
src="image.jpg"
sizes="(min-width: 800px) 800px, 400px"
srcset="version-a.jpg 400w, version-b.jpg 800w, version-c.jpg 1200w" >

# Shorthand

  • for fixed sized images, both the following versions are identical
  • the x notation can be used in place of the w notation
  • browsers don't need to take screen size into consideration, only its DPR
    • indeed, this was the original, more limited, responsive image specification
<img
src="image.jpg"
sizes="400px"
srcset="version-a.jpg 400w, version-b.jpg 800w, version-c.jpg 1200w" >

<img
src="image.jpg"
srcset="version-a.jpg, version-b.jpg 2x, version-c.jpg 3x" >

# Art Direction with picture tag

  • the above sizes attribute selects differently sized images based on media conditions
    • recall a small screen with high DPR can use the same image as a large screen with low DPR
  • to support art direction, ie, to select a differently cropped variant based on media conditions requires a 2nd selector level
  • use media attribute on the source tag with sizes and srcset attributes; within the picture tag
<picture>
<source media="(max-width: 799px)" src="..." sizes="..." srcset="...">
<source media="(min-width: 800px)" src="..." sizes="..." srcset="...">
<img src="image.jpg">
</picture>

# Resizing and recropping

  • responsive images require multiple sizes and crops of the same image
  • statically generate at build time, or dynamically generated (and cached) at request time
  • many self-hosted  or paid  image resizing options available

# Image breakpoints

  • with CSS, breakpoints are usually determined by container sizes, like the screen size
  • with images that fill their containers (are not fixed size), breakpoints should be determined not based on media conditions, but on file size 
    • different images compress differently, and at different sizes
    • select srcset based on jumps in file size, rather than jumps in image size
    • ie, done at image selection/upload time per image, rather than design time per design

# Vector images

# Conclusion

  • responsive images allow sites to deliver the highest quality images on high-end devices
  • as well as best crops depending on screen size
  • at the same time, not overwhelm low-end devices with unnecessary data