
Image above credited to this site.
This post was originally published on August 21, 2009 and is now being being republished as it has been entirely revised. Both original methods are removed and now replaced by four new methods.
The goal here is a background image on a website that covers the entire browser window at all times. Let's put some specifics on it:
- Fills entire page with image, no white space
- Scales image as needed
- Retains image proportions (aspect ratio)
- Image is centered on page
- Does not cause scrollbars
- As cross-browser compatible as possible
- Isn't some fancy shenanigans like Flash
Awesome, Easy, Progressive CSS3 Way
We can do this purely through CSS thanks to the background-size property now in CSS3. We'll use the html element (better than body as it's always at least the height of the browser window). We set a fixed and centered background on it, then adjust it's size using background-size set to the cover keyword.
html {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
Works in:
- Safari 3+
- Chrome Whatever+
- IE 9+
- Opera 10+ (Opera 9.5 supported background-size but not the keywords)
- Firefox 3.6+ (Firefox 4 supports non-vendor prefixed version)
Update: Thanks to Goltzman in the comments for pointing out an Adobe Developer Connection article which features some code to make IE do cover backgrounds as well:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";
But careful, reader Pierre Orsander said they tried this and had some problems with links on the page going dead.
Update: Matt Litherland writes in to say that anyone trying to use the above IE filters and having problems with scrollbars or dead links or whatever else (like Pierre above) should try NOT using them on the html or body element. But instead a fixed position div with 100% width and height.
CSS-Only Technique #1
Big thanks, as usual, to Doug Neiner for this alternate version. Here we use an inline <img> element, which will be able to resize in any browser. We set a min-height which keeps it filling the browser window vertically, and set a 100% width which keeps it filling horizontally. We also set a min-width of the width of the image so that the image never gets smaller than it actually is.
The especially clever bit is using a media query to check if the browser window is smaller than the image, and using a combo percentage-left and negative left margin to keep it centered regardless.
Here is the CSS:
img.bg {
/* Set rules to fill background */
min-height: 100%;
min-width: 1024px;
/* Set up proportionate scaling */
width: 100%;
height: auto;
/* Set up positioning */
position: fixed;
top: 0;
left: 0;
}
@media screen and (max-width: 1024px) { /* Specific to this particular image */
img.bg {
left: 50%;
margin-left: -512px; /* 50% */
}
}
Works in:
- Any version of good browsers: Safari / Chrome / Opera / Firefox
- IE 6: Borked - but probably fixable if you use some kind of fixed positioning shim
- IE 7/8: Mostly works, doesn't center at small sizes but fills screen fine
- IE 9: Works
CSS-Only Technique #2
One rather simple way to handle this is to put an inline image on the page, fixed position it to the upper left, and give it a min-width and min-height of 100%, preserving it's aspect ratio.
<img src="images/bg.jpg" id="bg" alt="">
#bg {
position:fixed;
top:0;
left:0;
/* Preserve aspet ratio */
min-width:100%;
min-height:100%;
}
However, this doesn't center the image and that's a pretty common desire here... So, we can fix that by wrapping the image in a div. That div we'll make twice as big as the browser window. Then the image will be placed, still preserving it's aspect ratio and covering the visible browser window, and the dead center of that.
<div id="bg">
<img src="images/bg.jpg" alt="">
</div>
#bg {
position:fixed;
top:-50%;
left:-50%;
width:200%;
height:200%;
}
#bg img {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:auto;
min-width:50%;
min-height:50%;
}
Credit to Corey Worrell for the concept on this one.
Works in:
- Safari / Chrome / Firefox (didn't test very far back, but recent versions are fine)
- IE 8+
- Opera (any version) and IE both fail in the same way (wrongly positioned, not sure why)
jQuery Method
This whole idea becomes a lot easier (from a CSS perspective) if we know if the aspect ratio of the image (inline <img> we intend to use as a background) is larger or smaller than the current aspect ratio of the browser window. If it is lower, than we can set only the width to 100% on the image and know it will fill both height and width. If it is higher, we can set only the height to 100% and know that it will fill both the height and width.
We have access to this information through JavaScript. As usual around here, I like to lean on jQuery.
<img src="images/bg.jpg" id="bg" alt="">
#bg { position: fixed; top: 0; left: 0; }
.bgwidth { width: 100%; }
.bgheight { height: 100%; }
$(window).load(function() {
var theWindow = $(window),
$bg = $("#bg"),
aspectRatio = $bg.width() / $bg.height();
function resizeBg() {
if ( (theWindow.width() / theWindow.height()) < aspectRatio ) {
$bg
.removeClass()
.addClass('bgheight');
} else {
$bg
.removeClass()
.addClass('bgwidth');
}
}
theWindow.resize(function() {
resizeBg();
}).trigger("resize");
});
This doesn't account for centering, but you could definitely alter this to do that. Credits to Koen Haarbosch for the concept behind this idea.
Works in:
- IE7+ (could probably get in IE6 with a fixed position shim)
- Most any other desktop browser
Enjoy
If you use this, please feel free to leave what technique you used and if you altered it in any way in the comments below. Always cool to see techniques "in the wild."
Just for posterity's sake, there is another example in here called table.php which uses an old technique that used to be a part of this article. It had some cleverness, but wasn't quite as good as either CSS technique now presented above.
Other Resources
- jQuery plugin: Vegas, by Jay Salvat
When the background-image gets upscaled it seems like it’s pretty heavy for Firefox (maybe other browsers too) and if you scroll through the site there is an obvious delay there.
Nice effect though, thanks!
Yep. In Chome there is a delay.
Nice follow up to the previous article. I personally wouldn’t have thought of using a table – the bogeyman of web design!
Works nicely though.
This is awesome! very clear in w200% and h200% then -50% positioning!
Table is perfect fine because its only holding a image. The content you concern about with accessibility is on the DIV.
Fine!? A table is fine if you like to poop all over semantics and proper use of HTML elements.
This solution is ugly as sin, a javascript workaround would be far more elegant (if done properly).
did he say “poop”? :D must have kids. haha
It never ceases to amaze me how much hate tables have generated within the design community :)
@ Josh #2
Blatant incorrect use of tables have generated a lot of hate and rightly so.
Oh, I think that’s almost the definition of hate, isn’t it? It makes you sort of irrational.
The problem with tables was lots and lots of them everywhere, for no reason.
This, OTOH, is a beautiful solution with a tiny little table. Oh, who cares?! :-)
I agree that it’s fine – it’s not as though in a real world situation you would be entering the site for awards.
Sure, divs are purposely designed for layout. But in a business sense (which is how we all put food on the table), sometimes the quicker way is using a table here and there.
Unless otherwise specified, I sincerely doubt that a client or employer would care – I haven’t come across one.
This is a fantastic solution + especially that it is cross browser compatible which is far more important.
tables … geeze …. those who moan about how bad it is generally have less than perfect websites themselves … lol …. nothing at all wrong with tables if used correctly and this is a prime example of very good use.
WELL DONE and thanks
thought about how to do this yesterday, and then you post this today. This is really great!
Thanks
nice tips. btw, how trick if the image in code css?
Just a little nitpick,
Fills entire page with image, no white space
On the Demo, when the window is less then 1125px wide there IS white space on top and bottom.
I think this space is more likely to appear on a user’s screen then when there is white when the window is bigger then 2560px (with a big image and overflow:hidden) – the latter is not the case in this demo, but is here
In Chrome 2.0.172.39 i see background at top and bottom of page (on Your example and on http://ringvemedia.com/), and in Opera 9.64 i see scrollbars on Your example. On http://ringvemedia.com/ scrollbard doesn’t show.
The latest Opera looks fine to me, but indeed there is a bug in Chrome (mac). I’m gonna hold off on sweating that until there is a final mac version I can test on.
http://img29.imageshack.us/gal.php?g=chromeq.jpg these are screenshots taken from my home desktop, but problems are the same @ work, there i’m on XP, here on Win 7.
Opera screenshot is from 10beta, but i’ve got the same problem on 9.64.
That was taken in the few minutes while I was working on a new idea to fix the focus/scrolling problem…
But Opera is still kinda borked.
Man, the Opera users really come out of the woodwork when you post a technique like this.
Thanks for taking a look and breaking this down. I found an earlier method listed on this site, too, http://css-tricks.com/how-to-resizeable-background-image/ but I ended up using the method Anders uses on http://www.cssplay.co.uk/layouts/background.html.
Seems there are always several ways to accomplish the same thing….still not sure how tables works in this case but fun to take a look nonetheless.
Thanks!
Doug
The CSSPlay method looks to resize the image though, which can be undesirable.
Anders method doesn’t preserve the aspect ratio does it?
I agree with Chris that the distorted aspect ratio is quite undesirable.
It’d be great if we could do this without the use of a “layout-table”, BUT this is a fantastic effect and perfect for photo blogs, portfolios, etc.
Thanks for sharing!
Nice effect Chris, I’ll definately get some use out of this one. Good job.
This technique (at least the demo and the ringvemedia site) don’t work very well in Safari 4.0.2
The horizontal scaling sort of works but the vertical stuff doesn’t.
Screenshot
It seems to be the min-height attribute on the image that isn’t taking in Safari 4. Not sure what the solution is going to be there. JavaScript might need to get involved, unfortunately.
Nice proof of concept, I like these types of posts. Thanks.
Another way to do this trick that i use, is to use jquery tlike this
to explain this, with jquery i’m getting the height and width of the window then using php gd i’m resizing my background to the good size
What kind of success have you had doing it with jquery and php? Does it work in all browsers ?
This is a really bad way to handle full screen backgrounds, geekbay. I take it you’d run this on $(window).resize(), not $(document).ready()? This means you’ll call a PHP script and have GD resize the image every single time the window is resized! Do you know how much memory that will use?!
just a little glitch it’s:
$(body).style(‘background’,'url(phpthumb.php?src=bg.jpg&w=’+w+’&h=’+h+’)');
Pretty clever =)
Would you mind explaining this a little more? Is this function inside the document ready function? A little more insight in terms of implementation would help me understand.
Thanks
From what I can see, this either:
a) doesn’t resize with the window
or b) re-requests the image whenever you change the window size.
More importantly, this technique prevents the browser caching the background image – which, for big images like these – is critical.
Very cool trick. Can’t CSS3 implement this also? I know it’s not friendly w/ IE yet. Just curious.
I have seen this before too. Was inspired by it originally..
Hmmm, on FF3.5, if I press “space” the whole page scrolls…
I fixed the space bar issue by appending a hidden input with javascript and setting the focus to that. Kinda hacky but fixes the bug for now.
Alright I documented the current known bugs at the bottom of the article. If you find fixes or more bugs, let me know.
The page scroll can actually be done with the space bar, but also with the arrow keys, for horizontal and vertical scrolling.
I suppose it’s a focus problem; anyway for accessibility it would be better to have the focus on the center element.
So it means… javascript.
The only problem I see is the image definition. If you load a huge image into a small window, rescaling may make it look funny, or a image let’s say 1280px large will show big pixels on a huge screen. I generally load a standard image of 1280px as background and overload a bigger one in Ajax if the screen is wider. There is no rescaling in that case but at least there is an absolute control over the background image quality.
This seemed to work fine for me: Supersized
This reminds me of the new WPC2 system I just recently created.
I can’t say too much, but this does make me want to recreate your example with my technique used for resizing the WPC page to see if most of your bugs disappear. If I have any success I’ll reply to this comment and let you know
This is awesome! I thought this was only possible using flash. Thx for the post. Will definitely be using this for a photo gallery page.
The Image bar comes up on IE 6 if you hover over the image
i.e. the Save print etc. buttons that IE overlays.
You might want to kill that, it ruins the effect, Im sure there is some way to do that
Very nice, will give it a try. Thanks!
Was looking at this site’s solution for background images too
http://www.type3digital.com/
Bump – how did they do this?
Yup that question stayed in my head too…:D
I will be using this with one of my clients. Really beats the Javascript I was using. Thanks!
In the demo, in IE8 at least, the mousewheel only scrolls the content when the cursor is inside the white text container, and it’s somewhat sluggish at large resolutions.
Great that it works with CSS, but too many bugs to be used effectively.
I use supersize 2.0 for the same effect (also has transition). I used it here.
Agreed. Supersize 2.0 looks great. Does IT have any bugs or inconsistencies? What if a user doesn’t enable JavaScript?
There is a scroll bar in Opera 9.6, and it scrolls down to white space
Thanks for this – spookily just when I needed it!
There is also a vertical scrollbar in Opera 10b3, but it’s for the text – however, if I scroll down (without clicking the text first) it will scroll the image instead of the text.
In fact, if I middle click on the page, I can scroll to reveal white space both on the y- and x-axis in Opera, Firefox 3.5, Chrome, Safari4 and IE8. This is also the case for whatstheweather, but then only in the right-hand side.
~ Nix
the scrollbar ‘bug’ in FF3.5 isn’t a bug. that’s a keyboard shortcut to scroll down on any page. try it on this page, or google news, or where ever. the shortcut works in Chrome and IE8, too.
The “bug” refers to this technique, not Firefox itself.
I do get whitespace on the top and bottom if the browser is taller than wider of the image proportions. This needs to zoom-center.
can someone explain to me why exactly it is necessary to use a table for this effect? I am assuming that there is some innate abilities a table has that make this possible, but I am not sure what. Learning xhtml from the start I am not very table savvy ;)
Hmm, it’s nice in theory, but current browsers seem to be rather laggy on resize and scroll – And unless you use a high resolution image, chances are you’re going to see very unprofessional artifacts. Good to know for the future though =)
Hi Chris. Thanks for posting this. The NorthFace site has similar functionality but it looks like they use a flash solution.
I love this! This is one of those CSS Tricks I love to see appear rss feed! Alot of people don’t seem to like this, because of little bugs and the evil devil child of the internet design tables. My personal view on this is I hate tables but if it achieves the job without the use of flash or javascript then a table is okay. Semantics is only good and a guide to follow if you can afford it. Lets all remember that the objective is to design nice looking working sites. And these are some damn nice css tricks!
Thanx for thip great tip! I think, i will be use this trick on many sites;) This trick work on ie 5.5. Good Job!
I do something like this:
http://dump.myxcp.net/de…..ound.html
Lacks being centered vertically but works well regardless. Or you can make it 100% height and 100% min-width (then it can be centered horizontally easily).
@monkey56657 I did notice on your example that if your browser is not resized in proportion to the image, it does not cover the entire background vertically.
There’s some funkyness when the browser gets really short in technique 1.
but Technique 2 works great :) Thanks.
In technique 2: If you set the img.bg bottom: 0 instead of top: 0, you can anchor the image to the bottom of the browser window instead of having it anchored to the top. If you had a city-scape or other bottom-designed image, this would become very important.
Technique 2 is very good addition to the article.
@Chris: Could you somehow indicate that this article has been updated ?
Thanks for posting this. One question, why use a table? Anyone tried this without a table and have it working?
There’s a problem in FF3: if i use mousewheel, i can scroll left and down and the white space occurs
If you just mousewheel scroll it, you would see white space all around.
Did you check that?
Nice work Chris, Full page backgrounds are something that I have always been intrigued by, but never really got my head around, due to different image dimensions, screen resolutions etc.
I was sort of under the impression that you would dynamically select a particular image depending on on the client browser size.
This looks pretty good though!
Hi Chris,
i only see “picture” placeholder text in Opera 9.64 on Vista Business 64 Bit. While Firefox shortly renders the page with a background picture and then redirects to your 404 error page…
Greetings
Mathew
Hi Guys,
I love this solution. It’s embed swf obviously. Any idea what’s the Action Script inside of .fla file looks like :) ?
it’s not flash. it’s javascript.
I may have missed it, but is anyone else having trouble displaying the bg image with IE7 or 8? It works beautifully in every other browser, but I get the broken image logo on IE. ugh! I’ve tried both techniques, by the way.
Massively impressed with this and it’s even better now that Doug has came up with a pure CSS solution!
Thank you for the great lesson. Yet, frankly I’m hesitate to apply the technique into my site. Sometimes I include table into DIV tag and the table jumped out of the main wrapper.
Very nice. I will try this on my next project.
Finally I found a good tutorial as well. Thanks
cool. adding this to my faves.
I had to tackle this problem myself recently and have come up with a fairly decent solution that is standards-compliant, uses minimal code (just one extra div), doesn’t use flash and seems to work in all browsers. Try this: http://blog.urbanmainframe.com/2009/05/create-a-dynamically-resizing-background-image-using-css/
Excellent! And what timing…
I saw the site a while back and wondered how they did it. Then I let it go since I couldn’t figure it out thru code!
Kudos for this article!
http://normalbookmark.com/ has a nice JS implementation of the full screen background.
I personally prefer using swf (flash) solution. swf file can be less than 15kb (compressed). I also checked flash samples that people posted above, all look perfect in all browser. Pure CSS solution is nice one, but probably it depends on your image and how big it is, and resizing it a bit tricky if you ask my opinion. In addition, with using flash, resizing is much better handled by flash (speaking from experiences)…http://www.beyondfayte.com is using flash background, yes the site is full flash, but notice the background how beautifully constructed and transitions. Now, image for sec., take that swf file, and implement your site (html and css)….
Nice effect though,Works nicely .
I saw this trick some time ago and also used it… it worked like a charm, but at the moment, using safari there is some problem. it doesn’t adapt in vertical. when the window is not “wide”, the photo doesn’t deform showing the white background here in the demo and the “loading” background on the credited site. But I remember that when I saw that site some time ago I didn’t noticed this problem.
Question – how do I get the best of both worlds? A scrolling page with a full static background. They showed one here – http://ringvemedia.com/introduction.
Hi Chris,
First of all, thanks for the great article.
I am using the Tecnique #2 and I’ve encountered some strange behavior when I started adding additional divs inside the content wrapper.
I don’t want to crowd this side with code but here is the page online
http://www.brentwoodrestaurant.com/bg_test.html
As you’ll see I am trying to put some distance between the divs using margins but when I apply a margin to a DIV that margin gets applied to the parent div for some reason.
I hope I was able to explain my problem and that you have a solution for it.
I am not sure if this is a bug with the script or my fault.
Thanks a lot in advance.
Never mind, I think it was entirely related to my nested divs, nothing to do with the script.
Interesting way of doing it. Seems to work well, thanks :-)
ok so how can we implement this into a wordpress theme?
can we get some help for wordpress users? no one ever talks about where to place this code and even if anyone is using under wordpress. any help is appreciated.
I think this is very well done though I do have a theory…
If you’re not adverse to marrying up your solution along with some php and javascript then you could use js to get the window height and width, then using Joe Lencioni’s Smart Image Resizer you could target your image thusly:
I would think you could actually resize the images as opposed to just scaling them and thus keep the download times at a minimum. Though this may only create the resized image on page load… and then the rest of your solution could scale it from there…
this is all just thinking aloud. I love Joe’s solution and use it all the time and think that you could incorporate it into this idea with great effect.
Supersized (http://buildinternet.com/project/supersized/) works very well and can be tweaked to allow for content with scroll.
Here is an example: SOUND Phuket http://www.soundphuket.com
Check the calendar page which has a scrollbar.
Yo, there is a mistake in your description!!
change it ffs. took me an hour figuring this out. I guess all the other people were taking the code from the demo site, where it was correct, that’s why nobody else noticed it. (Or maybe I just missed something in the beginning :P).
Anyways, in the description of the technique:
html, body, #bg, #bg table, #bg td {
height:100%;
width:100%;
overflow:hidden;
}
BUT! in the demo site:
html, body, #bg, #bg table, #bg td, #cont {
…
.
The missing things was the 100% height and width on the #cont. Without it the scrollnig did not function in any of browsers.
cheers.
For technique 1, there seems to be an issue in Opera 10 if you use the scroll wheel or keyboard arrows down.
Indeed, then you see white space you don’t want to be visible.
The solution is to add this to the CSS:
#bg { position: fixed; }This works in all browsers.Nice post, I’m not a big 100% anything fan but this seems to work really well and might even try it out it in one of my site designs, so thanks for this.
Trying to figure out why the image will not show with DW? I even tested it out with EW3 and it works there…any ideas?
The div container that allows for content to be shown leaves a big white box in the middle of the page.
I’d like to request a further tutorial explaining in depth how to make all boxes of coding transparent to blend in with the image so that we may post whatever links and content we want into our respective websites.
A little extra info and we should be able to do virtually anything.
I’m very happy to find it, indeed. I’m photographer and sometimes I use to develop some photography websites, as former graphic designer.
Just a note that the technique #2 streches the image if we F11 the browser.
Thanks for sharing!
Ok I have one final issue to resolve on my website. How do I get the content box to make the paragraph tags separate.
My main page has a bunch of paragraph tags in it but they’re all bunched together instead of being spread out after being put into the content box.
I’m a little late catching on to this, but I love it! This changes my approach to design significantly. Thank you Chris.
This seems like a good solution, specially for clients who can be picky about what gets displayed to visitors. The only downside I can see here is the interpolation/resolution for larger monitors vs background file size. Great stuff. Thanks
Awesome stuff…!
It solved all my “oh no!-no-image-background” problems. :D
It helped me very well esp. for my computer project.
-thumbs up-
Thanks, great read. I find all technique, other then the CSS3, as partial and as short term solutions, semantically problematic, ans as mentioned above – performance challenged. I wouldn’t compromise on caching for this kind of a problem.
see my css3 solution implemented at stage-center.org
In CSS-Only Technique #2 right styles for image should be:
#bg img {
position:absolute;
top:25%;
left:25%;
right:25%;
bottom:25%;
margin:auto;
min-width:50%;
min-height:50%;
}
Note the 25% positioning it’s necessary in order to place image properly. That’s why the method fails in Opera. I didn’t tested it in other browsers yet.
But according to CSS 2.1 «Visual formatting model details» it’s a real bug that absolute positioned image aren’t centered with margin:auto.
Great post ..thanx yaaa
The new CSS3 method is awesome. It seems that I’m asked to do this technique on a little less than half my projects anymore. I think from now on I will do a combination of the CSS3 method with a fallback for older browsers using one of the other techniques.
Thanks Chris for another great post!
I’ve been exploring all kinds of non-flash fullscreen solutions for my designs. One thing I wanted to find is a cross browser solution which
a) Resized using the center for the image and not the top part
b) Was able to fade in on page load (with full ‘preloading’ control)
c) Used a minimum amount of code for fast page rendering.
Supersize was one of my first choice. But its JS was conflicting with other elements and I did not like the fact that the image could not fade in nicely all the time. Depending on what is was going on page load, there was no sure way to control the process.
I then found another approach which works as far as I can tell in all browsers, does not use JS or Flash and answered my requirements.
It’s a mix of CSS and the use of Tables. I know… it’s not ‘pure’, but it does the trick so well…
I was able to target the img with JQuery to have it fade in on page load exactly as I wanted – once the image was really ready for display – no room for error and no room for JQuery launching the fadein before the image had finished downloading.
I implemented it here : http://www.cadranhotel.com/.
Credits for this technique goes to : http://www.g2geogeske.com/ (which is where I first saw this concept and expanded from it).
This is my solution, a Dojo Toolkit module. If it is possible it uses CSS3, if not, falls back to JS.
http://code.ttcon.hu/fullscrn/
Wow, did not know about that CSS3 property, that will be amazing for the future.