Responsive Images

Support for CSS3 media queries in browsers has led to much excitement and debtate with regards to delivering alternate web site layouts depending on the screen width – just check out this web site by resizing your browser window from full-width down to a very narrow view.

The main problem when designing for different screen sizes (large desktops and small screen mobile devices) is managing image size and scaling. Whilst browsers that support media queries can use max-width:100%; to scale images to the width of the container (see Ethan Marcotte’s article Responsive Web Design) it doesn’t solve the problem of small screen devices still downloading a large image designed primarily for desktops – you can’t really say your web site is ‘mobile friendly’ if it weighs in with some hefty image file sizes.

An interesting solution – jQuery and HTML5

I thought about this for a while and enlisted the help of my colleague and ColdFusion master John Whish. After much discussion and research John jumped in and helped code a very quick HTML5 and jQuery example.

Check out the demo

So how does it work?

  1. Firstly we need to make the content of the page expand and contract depending on the width of the browser using CSS3 Media Queries. If you don’t know much about Media Queries I would recommend checking out the excellent Less Framework which has been of great inspiration to me. Using the same defaults of Less Framework we have four layouts:
    • 992px – default for desktops and large screens
    • 768px – for tablets
    • 480px – for landscape mobiles and small tablets
    • 320px – for mobile and small screen devices

The following CSS3 will deliver different style declarations (width and padding) for a div called wrapper:

/* Default Layout: Other layouts inherit #wrapper declarations */
#wrapper {margin:0 auto; width:896px; text-align:left; padding:17px 48px 50px;}

/* Tablet Layout: 768px */
@media only screen and (min-width: 768px) and (max-width: 991px) {
  #wrapper {width: 712px; padding:17px 28px 60px;}
}

/* Wide Mobile Layout: 480px */
@media only screen and (min-width: 480px) and (max-width: 767px) {
  #wrapper {width:436px; padding:17px 22px 48px;}
}

/* Mobile Layout: 320px. */
@media only screen and (max-width: 480px) {
  #wrapper {width: 252px; padding:17px 34px 60px;}
}
  1. We have four layout sizes so we need to create 4 images. Create the largest image first then scale or optimise depending on your requirements. I append either -m, -mw, -t or -d to the end of each image for mobile, mobile wide, tablet and desktop. The width of the images depend on your layouts and the width of the parent container. For the purpose of my demo I have used images with widths of 896px, 712px, 436px and 252px.

  1. Once you have four images add them to your HTML5 page using the example code below. The reason we use HTML5 is so we can use the ‘data’ attribute which validates correctly. The data attribute can be called whatever you like providing it is prefixed with data-. For more information about the data attribute the following article on HTML5 5 doctor is very good.
<img src="imagename-m.ext"
data-src-mobile="imagename-m.ext"
data-src-mobile-wide="imagename-mw.ext"
data-src-tablet="imagename-t.ext"
data-src-big="imagename-d.ext"/>
  1. Make sure you link your HTML5 document to the jQuery library.
  2. Add the following jQuery code to your HTML5 document. I’m not going to break it down line by line – essentially jQuery will load each image and replace the default ‘mobile image’ when the browser window hits a specific width.
<script type=text/javascript>
jQuery(function($){
      loadOptimisedImages = function() {
      // get the document width
      var documentWidth = $(document).width();
      var screenType = 'mobile';

      if (documentWidth >= 991) {
       // big screen
      screenType = 'big';
       }

      else if (documentWidth >= 768) {
      // big screen
      screenType = 'tablet';
      }

      else if (documentWidth >= 480) {
      // medium device, for example a tablet
      screenType = 'mobile-wide';
      }

      $('img[data-src-' + screenType + ']').each(function(){
      $this = $(this);
      $this.attr('src',$this.attr('data-src-' + screenType));
       });
  }
      $(window).bind('load resize', loadOptimisedImages);
});
</script>

Benefits

  • Mobile and small screen devices will only load the smallest image. This could reduce the page weight considerably.
  • You can serve different images, for example if you have a detailed image that works well at large sizes you may decide to zoom in or focus on part of the image for your small screen version.
  • Remove Images from small screen layout – It’s a common technique to use display:none in the stylesheet to remove images from small screen layouts. Visually this works but the image is still downloaded in the background. Using this method you have the choice not to display any image for a small screen and thus no download will occur.
  • And the not so good…

    • Image creation – producing four versions of the same image might be seen by many as a nightmare scenario, especially when it comes to making quick edits to a web site. I agree. The fastest solution is to have a template set-up when you can quickly save out four different versions. You don’t need to produce 4 images though, you could just have one for small screens and a large one for the others. Whatever suits your needs.
    • Double Download– we need to specify a default image so those people who do not use Javascript will get a ‘fallback’ image (in this case the small mobile version) rather than nothing at all. This means that the small image is downloaded as well as the correct version hence a double download. There is a way to avoid this by specifying src=”about:blank” however, if a user doesn’t have Javascript they won’t see any images.
    • Image load delay– the small image loads first followed by a brief pause before the desktop version loads.
    • So… is is worth using?

      I don’t think this solution is perfect, far from it. However, its a fairly straightforward and is easy to implement and in certain cases will work quite well. If you have a simple site with large images such as a portfolio or photo page you can quite easily reduce the page weight.

      The whole area of responsive/adaptive design is fascinating to me. As new devices and thus screen sizes appear on the market the goal of delivering fast viewing experiences will promote new ways of delivering the correct imagery to suit.

This entry was posted in HTML5, jQuery. Bookmark the permalink.

2 Responses to Responsive Images

  1. Mårten says:

    One way to avoid the flickering is to add width and height definitions in the css per screen size, so that you instead get a blurred image for a short while, and the it “sharpens” when the real image is loaded.

  2. andy says:

    Mårten, thats a very good and simple solution I should have thought of. Thanks :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>