français
english

Resizable, full-width hero images that scale to a central area

Ever wanted to provide a hero image that spans the entire width of the browser regardless of width, yet under a certain width starts to scale smaller? For an example of what I’m talking about, see the example I’ve put together.

Notice that the central area of the hero image remains fixed with browser widths from 960px and wider, but that when your browser gets wider, the image gets wider. Not too difficult – simply a wide, centered image you say. Now make your browser narrower than 960px. You’ll notice that the image starts to scale down, but the central area remains the same – the images does not scale to its own width, but to its height, yet based on the browser width. All is done via CSS and HTML structure. How does this work?

Here’s how.

First we have to realize that, almost since the original versions, browsers will scale an image’s width relative to its height when given a height to display, or vise-versa. Say we have an image of 960px×468px. If we tell the browser to display this image at 480px wide and do not specify a height, it will display it at 234px high.

Second we have to realize that with CSS3, we can scale a background image. The background-size property takes lengths (pixels), percentages, and a couple other values. This is supported by all modern browsers and IE9+.

So lets start with the structure needed. I include the CSS within style tags here for brevity here, but you will likely want to move most of it to a style sheet:

  1. <div style="width: 100%;">
  2.     <div style="max-width: 960px; margin: 0 auto;">
  3.         <img src="clear_960x468.gif" style="width: 100%;" alt="My Hero" />
  4.     </div>
  5. </div>


With this code we have the shell of what we need to make things work. You’ll notice that I don’t yet have the hero image in place, just a transparent image of 960px×468px. So why this image and why this size?

  • First, this image is what will allow the browser to automatically scale the central 960px×468px area as the window gets narrower. It is transparent so that it doesn’t interfere with our hero image and it also takes only 1k (it compresses easily).
  • Second, this size is integer divisible by 2, 3 and 4 in both directions so provides a nice solution for 320px-wide screens too. Of course, I would advise that for telephone and other 3/4G devices that this image be swapped out for a lighter-weight image, but that’s another issue. Scaling works well at these two dimensions.

So where’s our hero image? Remember we talked about the background image earlier on. We’ll add it here:

  1. <div style="width: 100%; background-image: url('hero_1920x468px.jpg'); background-size: auto 100%; background-position: center top; background-repeat: no-repeat;">
  2.     <div style="max-width: 960px; margin: 0 auto;">
  3.         <img src="clear_960x468.gif" style="width: 100%;" alt="My Hero" />
  4.     </div>
  5. </div>


We now have a hero image working exactly as we want, above 960px wide we will see the wider image, below this width we will see it start to scale down.  The operational part is the background-size property. It tells the browser to scale the width relative to the height (auto) and to make the height fit the div (100%). The div will resize relative to its contained image, which will scale relative to its div’s width (max 960px). The background-position ensures that the image is always centered in the browser width-wise;

The one piece of styling you may to keep in the HTML, especially if you are using a CMS solution to create your pages is the background-image properly. Like I said previously, the others are best relegated to a CSS style sheet.

Remember too, that for accessibility reasons you will want to include an alt attribute on the image. Even though it is technically clear, it is the area presenting the image, so is appropriate for the alt attribute.