Understanding Responsive Web Design: Responsive Imagery

This entry is part 4 of 6 in the series Understanding Responsive Web Design

Understanding Responsive Web Design

In this fifth part of our Understanding Responsive Web Design series, I’ll show you one of the typical problems that a web designer faces when building a responsive website: the management of the images. As you’ve seen so far, the challenges that a mobile designer faces are numerous, and it’s not so strange or unusual to think that one of the biggest is serving multiple image formats to multiple screen sizes. There are currently three strategies that a developer can choose when it comes to responsive imagery: he can choose between: “fighting” the browser, “resigning” himself, or relying on the server. Let’s try to understand the advantages and downsides of each option.

Fighting the Browser

Most front-end developers choose to apply the first strategy and fight the browser. What does “fighting the browser” stand for? It means doing your best to give the “right” image (that is, the image that has the correct size for the device used to view the website) to the browser so that it can be loaded before the browser had downloaded the “wrong” one (that is, the “default” or the desktop version of the image). This is an increasingly difficult task, as modern browsers and ever-quickening bandwidth means that users try to download images as quickly as possible.

Resigning

Sometimes the simplest and most comfortable strategy is the only viable option: admit defeat. Generally, this approach involves loading the default image onto small screens, and secondly, if necessary, loading a larger image for screens with larger dimensions. While this method is easy and straightforward, it’s not recommended, because in the second case, two requests are sent to the browser when only one is necessary.

Relying on the Server

The third strategy involves the use of the server, a server-side programming language and some basic forms of detection to determine which image to load. All of the logic is executed before the browser is able to see and interpret the HTML code. Unfortunately, this strategy has its own flaws: the act of maintaining an ever-growing list of mobile devices and screen sizes would become very complicated and require constant upkeep.

To help you understand better what this technique does and how it can be used, let’s consider an example. In the following example, I’ll show you a few lines of PHP, but don’t worry, you don’t have to me a PHP expert to create responsive images, and you’ll understand the example even if you haven’t worked with PHP before. Let’s assume that you’re creating a page dynamically and that you’re injecting an <img> tag using the following line of code:

echo '<img src="heavy-image.png" />';

As you might already know, mobile connections aren’t nearly as fast as their desktop counterparts. So, to speed up the rendering of your page for mobile devices, you’d like to inject a lightweight version of the image if the user is using… perhaps an iPhone. What you can do server-side is check the user-agent that made the request and—if the device was an iPhone—inject the smaller image. The next snippet demonstrates this technique:

if (strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') === false) {
  // Not an iPhone
  echo '<img src="heavy-image.png" />;
}
else {
  // An iPhone
  echo '<img src="light-image.png" />;
}

As you can see, the method is very easy to implement, however this approach isn’t very reliable because the user-agent information itself isn’t 100% reliable. If the method fails, you could have some glaring problems with your imagery.

Is One Method Better Than The Others?

Obviously, each approach has its own unique advantages and limitations, and it’s unlikely that one single method will be the ideal choice for all of your mobile projects. However, there are some additional techniques and resources that a developer may use to create responsive images.

Sencha.io Src

The first option is very fast and simple. It is a service developed by James Pearce that returns the image you choose to load resized to fit your exact needs. Its name is Sencha.io Src, and all you have to do is put the Sencha.io Src URL location of your image as the image’s source.

<img src="http://src.sencha.io/http://mysite.com/images/my-image.jpg" />

The service uses the user agent string of the requesting device to determine the desired image size and resize the image accordingly. By default, the image is scaled to 100% of the width of the screen. Sencha.io Src has a high level of customization; it’s possible to set a specific width or any other parameter. For example, if you want to set the image width to 250 pixels, you have simply to add the size into the URL as follows:

<img src="http://src.sencha.io/250/http://mysite.com/images/my-image.jpg" />

The service also caches the request, so the image will not be reloaded each time the page is loaded.

Adaptive Images

A similar solution is proposed by Matt Wilcox. It involves determining the size of the screen first, and then creating (and caching) a scaled version of the correct image dimensions. This is an ideal technique to make the images of an existing website responsive. After downloading the code (which you can find at adaptive-images.com), to make this solution operational and running properly, you need to follow three simple steps:

  1. Add two files, .htaccess and adaptive-images.php, to the root folder;
  2. Create a cache folder and allow write permission;
  3. Add the following line of Javascript code at the beginning of your document:
<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>

Thanks to this one line of code, the screen resolution is captured and stored in a browser cookie. It’s possible to configure multiple options in the file adaptive-images.php, but the primary purpose of the file is setting the variables for the resolutions ($resolutions).

$resolutions = array (800, 480, 320);

These resolutions are the “breakpoints” of images based on the screen resolution (a width to be measured in pixels). In this case, This tool will serve out a small, mobile-friendly image for devices with a pixel width of 320 or smaller. If the display exceeds 320 pixels, the new reference value is 480, which is the next numerical value in the array above.

Once created, the images will be stored in the cache folder (where you can change the filename), so that you will no longer need to generate them.

In addition to what I showed, I want to highlight that the key point of the discussion on adaptive images concerns their size. This is certainly an important factor, but we often forget that it is not the only one. For example, resizing an image for smaller displays often reduces the impact and the recognition of the image. In these cases, it may be necessary to modify the image. Even a simple cropping of the edges or of the superfluous elements can help the image retain it’s impact and significance at a smaller size.

Conclusion

In this article I described three ways to work with with images from a responsive design point of view. The first is fighting the browser—that is, doing your best to give to the browser the “right” image to download. The second is choosing services like Sencha.io which use the user agent string of the device from which the request is sent to understand screen size and resize the image accordingly. The last involves to adaptive images—in this case, the developer only needs to determine the size of the screen and the image will scale to accommodate.

In conclusion, between the three approaches discussed above, the one of the adaptive images is probably the best solution as it requires no dependency to another site or link. In the next articles in the series, we’ll examine other methods that a developer can use to manage all the images of a responsive website.

Want to learn more about Responsive Web Design? Check out SitePoint’s new book, Jump Start Responsive Web Design!

Understanding Responsive Web Design

<< Responsive Web Design: Custom Grid LayoutsUnderstanding Responsive Web Design: Cross-browser Compatibility >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://netsalarytax.co.uk Robert

    It’s not to taxing to do it in simple PHP.

    I have a script developed in php for all my content images that re-sizes them automatically from a higher quality source image.

    This is simple to do, and combined with user agent detection (which I don’t do yet) keeps it all in-house.

    I’m not a fan of 3rd party solutions, though for many people development is time wasted when they could be creating content, so it might suit them :)

  • http://photobr.org Bruce Norton

    I have been wondering if using TimThumb (using php to resize images on the sever and create cached files) combined with media queries would be a good strategy.
    -http://www.binarymoon.co.uk/projects/timthumb/

  • Karen

    How about using background images instead of img tags and then letting CSS take care of the different sizes (with different CSS files for different classes of devices)? I might be missing something (as I have been mostly just reading about responsive design, not actually doing it), but that seems to avoid the downfalls mentioned in this article.

    But it would have a downfall of its own, that Chrome won’t print background images (and other browsers have a setting for that, which I think is off by default in most). Printing isn’t an issue on something like a smartphone, but it would be on a PC. Thoughts?

  • http://community.systar.com Francis

    Another possible way of showing responsive images is to use CSS media queries and to set the image as a background-image of an html tag.
    Such as in the html code:

    In the CSS file or inside a tag:

    @media (min-width:960px){

    div#myImage {
    width:500px; height:500px;
    background-image:url(‘../images/bigImage.png’) }

    }
    @media (max-width:959px)
    {

    div#myImage {
    width:100px; height:100px;
    background-image:url(‘../images/smallImage.png’) }
    }

    • http://community.systar.com Francis

      Correction:

      In the html code:

      In the CSS file or inside a tag:
      @media (min-width:960px){
      div#myImage {
      width:500px; height:500px;
      background-image:url(‘../images/bigImage.png’) }
      }

      @media (max-width:959px)
      {
      div#myImage {
      width:100px; height:100px;
      background-image:url(‘../images/smallImage.png’) }
      }

  • http://www.delucamarketing.ch NetHawk

    @Robert: I assume the Images are cached (as Bruce suggested), otherwise it would put heavy load on the server if images would have to be generated every time. @Francis: this is a solution for backgrounds only but for being semantically correct, you can’t put content images in the Background. Background is design, “foreground” images are content.

    Thomas Fuchs (the guy behind script.aculo.us) suggested another method for this. In simple words: make the images as big as the biggest dimension required – or even bigger, but compress them highly (with more visible loss than usual). Implement them in a way, that they adapt themselves to their container (e.g. column size). Use media queries to resize the container to whatever width you need and voila. Since the (big) images are being rendered in a small size, the visual quality matches that of images with the proper size but less compression. Less bandwidth is used to achieve the same visual result plus it works with every size of the container (no matter if there are 2, 3 or whatever sizes defined in your media queries). I played with that method and it looks like Thomas is right. See all the details here: retinafy.me