Perfect responsive images: HTML5 <picture> and Bootstrap 4

Perfect responsive images: HTML5 <picture> and Bootstrap 4

Bootstrap 4 is in alpha release and has a brand new set of media queries and breakpoints. Where Bootstrap 3 had them in pixels, the new release of the popular responsive framework boasts breakpoints in ems. Let's harness the power of these new media queries to serve an image of the right size based on the device a user views our site on. We're going to save a lot of bandwidth for the small devices, and serve a beautiful large image for larger ones. We'll do that by using the HTML5 picture element and its powerful source tag and media and srcset attributes. Are you ready to start serving perfect responsive images?

Bootstrap 4 Media Queries

First, let's have a look at the brand new media queries and breakpoints that Boostrap 4 offers. They are tailored to match the newest devices, including iPhone 6s and iPhone 6s Plus:

// Extra small devices (portrait phones, less than ???px)
// No media query since this is the default in Bootstrap

// Small devices (landscape phones, 34em and up)
@media (min-width: 34em) { ... }

// Medium devices (tablets, 48em and up)
@media (min-width: 48em) { ... }

// Large devices (desktops, 62em and up)
@media (min-width: 62em) { ... }

// Extra large devices (large desktops, 75em and up)
@media (min-width: 75em) { ... }

As you can see, the queries use ems - instead of pixels - to tell devices apart, and break them into categories:

  • portrait phones
  • landscape phones
  • tablets
  • desktops
  • and large desktops

Let's make a mental - or written if your prefer - note of the four em sizes that Bootstrap 4 uses natively, as we're going to need them at the end of this guide. And let's head over to the next piece of the puzzle we're putting together.

HTML5 <picture> element

The picture element is one of the many smart elements available in the HTML5 specification, and allows us to serve a different image depending on the size of the browser viewport. The approach is much smarter than using a single image and resizing it in a CSS file or a style tag. We're not only making an image fit. We are serving a different image for each viewport size. A standard code example looks like this:

<picture>
  <source
    media="(min-width: 800px)"
    srcset="picture-large.jpg, picture-large-2x.jpg 2x">
  
  <source
    media="(min-width: 450px)"
    srcset="picture-small.jpg, picture-small-2x.jpg 2x">
  
  <img
    src="picture-tiny.jpg"
    srcset="picture-tiny-2x.jpg 2x" >
</picture>

If you're new to the picture element, maybe that's too much information to take in in one go. So let's break everything down and analyze each element separately.

picture

That's the wrapper tag that tells an HTML5-enabled browser that we are going to serve different image sizes depending on the viewport. All you have to do is put it around your source and img tags. As is, no attributes needed.

source

We need a source tag for each screen size we decide to serve. Each source will contain a media and a srcset attribute.

media

The min-width of our media query goes here. My guess is you are familiar with media queries. If you aren't, read more about media queries and responsive layouts. The min-width will trigger based on the viewport size and load the image source from our next attribute, srcset.

srcset

Our image source goes here. We're going to serve an image whose size is tailored exactly for the viewport that triggered our media query. For the more advanced users - and as you see in the code example above - this attribute can also be populated by a comma separated set of sources. Each of them will load a different image based on pixel density of the device. For instance iPhone 6s has pixel density 2x, where iPhone 6s Plus has 3x. That's it! Now we know everything we're going to need to use the picture element. Are you ready to continue our journey and adapt this knowledge to serve perfect sized images on Bootstrap 4?

Putting it all together: HTML5 responsive images for Bootstrap 4

What we're going to do now is simple: we'll take that standard example of the picture element we just examined and adapt it to harness the power offered by our Bootstrap 4 media queries. We'll need 5 different images, and for our final step we're going to use these example image names: extralarge.jpeg, large.jpeg, medium.jpeg, small.jpeg and extrasmall.jpeg:

<picture>
   <!-- Extra Large Desktops -->
   <source
     media="(min-width: 75em)"
     srcset="extralarge.jpeg">
 
   <!-- Desktops -->
   <source
     media="(min-width: 62em)"
     srcset="large.jpeg">
 
   <!-- Tablets -->
   <source
     media="(min-width: 48em)"
     srcset="medium.jpeg">
 
   <!-- Landscape Phones -->
   <source
     media="(min-width: 34em)"
     srcset="small.jpeg">
 
   <!-- Portrait Phones -->
   <img
     src="picture-tiny.jpg"
     srcset="extrasmall.jpeg" >
 </picture>

And our work is done. We're now serving responsive images: a perfectly sized image for each device our site is displayed on. We're saving bandwidth, and we're making sure our users see our images in the best format, adapted to their screen size. This is a responsive approach, so a different image will be loaded when a user expands and shrinks their desktop browser window. Have a play and see for yourself: keep your Chrome Developer Tools / Firebug open on the Network tab, resize the browser window, and see if a new image is requested each time you hit a breakpoint. If it does that means you did everything right. If it doesn't, go through this step-by-step guide again and double check your code against our examples! **Note: **The order of the source tags is essential. Start from the bigger sizes, proceed with the smaller ones, and make sure the default img tag contains the smallest image. Otherwise the browser will disregard our source tags and always load the image specified in the img tag.

And what did we learn?

Bootstrap 4 is about to be released, and is already available as an alpha release. We can harness the power of the new advanced media queries in ems and use the HTML5 picture element to serve responsive images - a perfectly sized image for each device our site is viewed on. That approach is elegant, saves bandwidth, and ensures each device receives the best looking picture.

Edoardo L'Astorina

Edoardo L'Astorina

Edoardo L'Astorina has 15 years of experience in software development. Edoardo has had a major role in the new Transport for London site and led the development of the new Royal Opera House site. Edoardo has developed sites and apps for Intuit, Stint, JPC, The Crocodile and Miura Edoardo started Blu Frame to help companies develop sites that stand out, load fast and are easy for users to access Edoardo is passionate about risotto, Terrence Malick movies, Oasis songs and rowing