How To: Resizeable Background Image

Is there a way to make a background image resizeable? As in, fill the background of a web page edge-to-edge with an image, no matter the size of the browser window. Also, have it resize larger or smaller as the browser window changes. Also, make sure it retains its ratio (doesn't stretch weird). Also, doesn't cause scrollbars, just cuts off vertically if it needs to. Also, comes in on the page as an inline <img> tag.

Wow, that's a tall order. My first thought was... uhm, No. But of course this is just the kind of challenge I enjoy, so I set about to thinkin'. Ultimately, I found a pretty good solution and we turned it into a pretty neat little project. First, check out the finished project, then I'll show you how it was done:

Finished Project: What's The Weather?Offline

Go ahead and resize your browser window around and notice how the image will resize to fit. It doesn't do it "on the fly", but it does work. It also meets all the other requirements: no scrollbars, and retains pixel ratio.

First Attempt

Well my first thought was that this really needs to be a CSS background-image. This will fill the screen edge-to-edge if the image is big enough. It also can be centered, so I figured this would be good enough. Large browser windows will reveal more of the picture and smaller ones less of the picture. If applied to the body tag, this will fill the screen nicely with no scroll bars. Pretty good solution I thought, even if it isn't technically resizeable, since you can't set the size of a CSS background-image. Here is how I went about this first approach.

You guessed it, jQuery. The above code will hide the image on the page, but snag it's "src" attribute and apply it as a background to the body element (via its unique ID "page-body"). Check out an example of this in action.

Second Attempt (better)

While the first attempt did a decent job, it failed at the most fundamental level: it wasn't "resizeable". So time for another take. In order to control the size of an image displayed on the screen without literally altering the file itself is to display it inline with the <img> tag. With the img tag, we can set "width" and "height" attributes to control the image's size. If we can get our hands on the exact pixel width of the browser window, we can use that number in the width attribute of the image and control its size while retaining the ratio.

We can, again, use jQuery and the dimensions plugin to get our browser window's width. Then we'll use that number to set the width attribute on the image, which we'll give a unique class name "source-image". We will need to do this as soon as the DOM is ready so it happens before the image even starts loading. We can also do this (FTW) any time the window is resized. Here is how it goes down:

In order to get this inline image to behave more like a background image, we can use that unique class we applied to apply some absolute positioning.

img.source-image {
position: absolute;
top: 0;
left: 0;
}

Because of this absolute positioning, anything that you want to put over it will also need positioning and a higher z-index value. If your source image is particularly tall, or your browser window is particularly wide, the image could easily become taller than your browser window and force a vertical scrollbar. In order to prevent this, simply set the overflow value on your body to hidden:

body {
overflow: hidden;
}

Third Attempt (best)

Forget this javascript business! Thanks to Anders comment pointing out Stu Nicholls version, here is an even better way to handle this without the need for any javascript at all!

Since we already have a unique class on the image, the image is absolutely positioned, and the scrollbars thing is already taken care of, let's just set the width using a percentage directly in the CSS:

See a demo of this in action. This is the best solution yet, because the resizing happens on-the-fly for a nice fluid feel, and doesn't rely on any javascript whatsoever.

More about WhatsTheWeather.net

I just did the simple design for What's The Weather(Update Nov 2013: now offline), but Richard did all cool coding to make it work. From what I understand, it is a chain of 3 different APIs. First it gets your IP address and uses an API to turn that into a city and state. Then it uses some weather API to get the current weather. Then it uses the Flickr API to get a random image with tags that match the weather. If if it can't get your zip, it will ask you for it, like on the iPhone (which it also auto-detects and handles a bit differently). All done up with Ruby on Rails. Pretty fancy dancin'!

Pretty cool! However you should include a way to check if the window is taller than the image to resize again and get rid of the white space that appears under some of them. I guess that means setting a height attribute in pixels and then applying a bit of math to work out the width and keep a constant ratio.

Elegant. In the true sense of the word. I had been looking for something like this a while ago, but fell back on using a larger image, and using overflow: hidden to keep the structure of the page (if not the whole image).

Probably not important to your weather pages, but setting overflow: hidden; on the body can cause problems in Firefox when you want to print a page that’s longer than one sheet of paper. As the content overflows the sheet only the first sheet will be printed. The second sheet will probably contain one more line but the rest of it will be empty.
It’s something to keep in mind when using overflow: hidden; on large block elements (not just the body).

You might want to make sure the ratio on the image is at least 4:3 to get rid of the unnecessary whitespace below the image… and make sure that if the bottom part of the image gets cropped off, nothing important is missing :)

So, what about IE6? Sucks that people still use this absolutely horrible browser, but I have a client who needs a dynamic background image that resizes and also has visitors who still use IE6. IE < 6 luckily enough, represents less than a percent of the visitors so I don’t have to worry about THAT browser.

One thing about whatstheweather though… could you have it detect which countries use Celcius/metric (like here in Australia), rather than imperial (it’s default) and change the temperature info accordingly. It got my city right (Perth, WA), but the weather isn’t “slightly cloudy” atm (it’s thunderstorms and hail), and fahrenheit means nothing to me. Once you detect if the city is in a metric country, then you could do a small conversion of whatever the fahrenheit is, to metric.

Anyway, love the proof of concept. I think it’ll be a while though before we all have decent enough internet speeds to be able to use it.

Oh Chris, I’ve been searching for you for so long. I am building a site in DW with drawn images in PS. I want to use them as background for each page and I need them to sit tight on the page just like the Weather, it just won’t work any other way. Trouble is I’m not a full bottle with code and don’t understand if you eliminated first three codes and went for the last? How do I get it in to DW, throught page properties ? I’ve tried every which way to resize in PS but it’s all guess work and either too large and starts to tile or too small with a white border. I am so desperate to move on and don’t understand when you speak in code. Would really appreciate help. Thanks Vicky.

Hi Chris, thanks for code. I have actually got this working albeit with a white border. I presume I now have to resize image to fit page. I have downloaded page dimensions plug in but am struggling to understand how to use. Will just have to keep going.
Thanks Vicky.

Your site is amazing and has helped me tremendously – not only to figure out how to do things, but also to see what kinds of things are possible within a browser window that I’d never thought of. I desperately need your help as it relates to a resizable background image – hopefully you see this comment.

The solution you’ve come up with here is great, but I’m looking for a little more proportional awareness – meaning, I’d like the background image to resize proportionally as you have it doing here, but then stop resizing if the user squishes the window to be much longer than it is wide. If a user does that with the solution you’ve come up with here on this post, you get white space underneath the image, which I don’t want. Here’s a flash site that does exactly what I want (though the background is video as opposed to a still image):

See how the background resizes, but at a certain width/height ratio it stops resizing so that the image continues to fill the window? I believe this function is contained in a javascript file called, “swfforcesize.js”, but I’m not sharp enough with the old javascript to parse out what’s actually at play here.

Any idea how to replicate this for a non-flash background? Any help you could offer would be tremendously appreciated.

I think the answer lies above in some kind of alternation to #2. Instead of just setting the width of the image to the width of the browser window, set it to the longest of either of the two sides (width of height). So no matter what, the width will be the longest and never create that white space.

This works for width, as noted, but still needs the proportion detection and adjustment for height as Chris Coyier noted. CSS is probably not able to detect these things, which is why you really need a javascript solution in order to handle all of this.

Has anybody made an implementation that solves the width OR height (proportion) thing?

I’m searching for ages for a solution, where the background picture resizes and keeps the porportions. But I haven’t found a solution, where the picutre filles still the entire screen, when you resize it in height aswell..
If somebody has an idea..?

Well, Flash, JavaScript, CSS, HTML – I really don’t mind which one – I searched first mainly for Flash codes – but I haven’t found satisfying solutions. That’s why I started looking for JavaScript and CSS..
Any idea how to solve that with flash?

Nathalie, have you seen my post on nov 5th? Is that something you are looking fore in css, xhtml?
You need to use the right Doctype to get it right with IE. I know that IE 6 and sp 2 (xp) don’t work to good. I don’t care much about ie 6.

Hi J. Im new to this, but your image scaling looks cool. I have been looking for a method how to doo this, after i saw the “go to china” site. Yours looks alot like it. How did you do this and in what program?

Hi J, this works really well. I presume this went in as a background image? How did you work out the correct size of your browser window? I also have links on my front page and need to make the links resize along with everything else. Any ideas. With thanks Victoria.

Hi,
I think I am having the same trouble that Victoria had. I know some code, but need some help knowing what to change. Every time I try to change the picture to the one I want, the new picture just becomes a background and does not change size.

It’s definitely the most elegant scaling solution I’ve seen. Dug through all of the js files I could find but they all pertained to the slideshow. No clues on the scaling yet. Unfortunately I’m still a javascript n00b.

I am trying to resize the background image without cropping any part of it. (no overflow:hidden) That I am sure we can do using height:100%.
I am having issue with applying the same to a particular section and the image is either stretched or compressed.

I’m working on a site for some friends whom have had a table based website. I’m not a CSS guru by any means and appreciated your tutorial on how to get the website background to stretch to fit using JavaScript. However, I’m have a hard to figuring out how to place my footer now so that it is at the bottom of the page. Can you firebug that page and let me know if you can suggest a fix for this problem.

That seemed like a good fix, but it didn’t work out. Some how now it is off the page all together. When I minimize the window and resize it can see that it is still on the page, but not in the footer area. Is there something in my footer css that is causing this discrepancy?

I have managed to do this but what I didn’t do was place the image as a background image. I placed it in a layer as close to the size of the browser window as possible. Then placed the background colour the same as the background of the image colour. This gets rid of any white borders. Victoria.

I just wanted to thank you for the inspiration in this article, I saw this and began working on a jQuery fix, this article helped a lot in getting me rolling on that. I’m a big fan of the blog, thanks again.

Wait a minute. Is it a background image or just an image? I know how to put a re-sizable image into a div, but I want a resizable background image. A background image is loaded through the css, and the advantage of using a background image is that it doesn’t hinder the page load time. Hence the need for a resizable background image. I think this tutorial is just teaching how to put an image into a div through html, and then styling the image through css. A true background-image needs to be loaded into the document like this:

#some id{
background-image: url(assets/image.jpg);

Am I just not understanding this tutorial right?

Thank you for any feedback. I really would like some help with getting a re-sizable background image.

This comment thread is closed. If you have important information to share, you can always contact me.

Treehouse is where you go to learn HTML, CSS, and how to build iOS apps. It's a complete education in modern web and app technology, designed to get you ready for a hot new job or to kickstart your own business.

The Lodge is a member login only area with access to video training on how to build websites from scratch using the best modern tools.

What now? I have some ideas for you.

Go explore CodePen!

As a front end designer and developer, you should have an account on CodePen so you can save your snippets, present your ideas, and engage with other front end folk. I'd encourage you to go PRO as well, to unlock the full power of CodePen.

Get the newsletter!

You should sign up for the CSS-Tricks newsletter. It's a clean copy of all the blog posts each week, combined together, right to your inbox. If email isn't your thing, there is an RSS feed, iTunes, and lots of other ways to subscribe.

Listen to ShopTalk!

Subscribe to The Lodge!

The Lodge is a members-only, ad-free video learning area here on CSS-Tricks. Just like the free screencasts, but organized into four large complete series. Membership is also the #1 best way to support CSS-Tricks.

We can do the real footer now.

Site Links

Colophon

CSS-Tricks* is created, written by, and maintained by Chris Coyier. It is built on WordPress, hosted by Media Temple, and the assets are served by MaxCDN. The fonts are Source Sans and Source Code Pro. It is made possible by viewers like you who subscribe to The Lodge and through advertising for products and services I like.