
We had decided that the new Grow Media site would be designed with a full-browser background image. We didn’t want a repeating image and we didn’t want a solid colour. We wanted the page to impact on first view. We had no idea how hard it would be to both design and then implement.
The first problem was at the design stage. Clean, simple and professional were the three most important design considerations. Grow Media had to be simple in both design and functionality. The problem this posed was that the images we began experimenting with were too busy and distracted from the content on the site. The image had to be “Grow” related; trees, grass, plants, general outdoor etc… We tried a number of images all with the same problem. Development began with one of the more problematic images. It is not always possible to get everything finalised in design before beginning development. It is always preferable to do so though.
To begin our search for the right script we set out goals. The script needed to:
- resize the image when the page loaded to fit full-screen in the browser
- resize the image when the browser window was resized
- resize the image whilst preserving the aspect ratio
- be as standards compliant as possible
- It needed to be small in size
- add as little markup to the page as possible
- stick to one JavaScript library
- be compatible with all modern browsers
The first script I looked at was one I had previously used for a site that needed a resizable background image. The script came from a site called GOTOCHINA. The site used only HTML and CSS to get a full-sized background image, although Mootools was used to make the technique compatible with Internet Explorer 6. For us, the main problem with this technique was that it used table elements to produce the effect. Our background is one of using as semantic markup as possible. This was not a semantic solution so it moved to the back of the que in case we came up with nothing else. The other issue with the GOTOCHINA method was its use of MooTools. We have no problem at all with any of the large JavaScript libraries. We have used the majority of them in various projects in the past. That being said we are most comfortable with jQuery and it is usually our goto library.
The next script we began looking at was a jQuery plugin called Supersized. The plugin is a Full-screen background/slideshow plugin. The plugin was comprehensive in the slideshow department and had a number of bells and whistles that were not needed in our project. I would recommend the plugin for full-screen image galleries though. It seems to work very well across all the browsers including IE6. For our purpose we just needed the resizing section of the code.
Code
Lets start with the HTML:
1 2 3 | <div id="supersize"> <img src="grass.jpg" /> </div> |
Then the CSS:
1 2 3 4 5 6 7 8 9 10 | #supersize { position: fixed; } #supersize img { height:100%; position:absolute; width:100%; z-index:0 } |
Finally the JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | (function($){ //Resize image on ready or resize $.fn.supersize = function() { //Invoke the resizenow() function on document ready $(document).ready(function() { $('#supersize').resizenow(); }); //Invoke the resizenow() function on browser resize $(window).bind("resize", function() { $('#supersize').resizenow(); }); }; //Adjust image size $.fn.resizenow = function() { //Define starting width and height values for the original image var startwidth = 1440; var startheight = 956; //Define image ratio var ratio = startheight/startwidth; //Gather browser dimensions var browserwidth = $(window).width(); var browserheight = $(window).height(); //Resize image to proper ratio if ((browserheight/browserwidth) > ratio) { $(this).height(browserheight); $(this).width(browserheight / ratio); $(this).children().height(browserheight); $(this).children().width(browserheight / ratio); } else { $(this).width(browserwidth); $(this).height(browserwidth * ratio); $(this).children().width(browserwidth); $(this).children().height(browserwidth * ratio); } //Make sure the image stays center in the window $(this).children().css('left', (browserwidth - $(this).width())/2); $(this).children().css('top', (browserheight - $(this).height())/2); }; })(jQuery); |
Explanation
Starting at the beginning lets work through the code to see how the resizing works. It is a very simple process.
Line 1 begins by opening an anonymous function and then on line 39 we close the function. This function allows anything inside the curly brackets to use the $ sign without conflicting with other JavaScript libraries. This code wraps all jQuery plugins so they work when using more than one JavaScript library.
//code goes here
})(jQuery);
The next section of code from line 3 to line 11 creates a function called supersize(). This can be called later in the code so we can resize the image on both DOM load and browser resize. By using $(document).ready we can call resizenow() when the DOM has loaded:
$('#supersize').resizenow();
});
By using $(window).bind we can call the resizenow() function as and when the browser resizes:
$('#supersize').resizenow();
});
The other function we need to create is the aforementioned resizenow(). This is started on line 14. Inside this function we can start getting our hands dirty and make changes to the image element. We begin by setting up the properties to hold the original height and width of the image (lines 16 and 17). This allows us to calculate the aspect ratio thereby preserving it.
var startheight = 956;
On line 19 we define the aspect ratio. This is a simple calculation that gives us a number to multiply the browser width by to find the height that the image needs to be to preserve the aspect ratio. Just to spell it out further lets do some math to understand what is going on here.
startheight = 667
startwidth = 759
ratio = 667/759 = 0.8787
Lets say the user has their browser at 1024 pixels in width and 768 pixels in height.
browser width = 1024
new height of image = browser width x ratio = 1024 x 0.8787 = 899.87 pixels height
Using that math we know we need some other properties to accomplish the resize (lines 21 and 22):
var browserheight = $(window).height();
With our ratio and the browser dimensions we can now work with the style and element properties to resize the image.
$(this).height(browserheight);
$(this).width(browserheight / ratio);
$(this).children().height(browserheight);
$(this).children().width(browserheight / ratio);
} else {
$(this).width(browserwidth);
$(this).height(browserwidth * ratio);
$(this).children().width(browserwidth);
$(this).children().height(browserwidth * ratio);
}
The first conditional statement checks to see if the browser ratio is greater than our original image ratio. If this is the case we want to divide the height of the browser by our ratio to achieve the width of the image. The else statement says that if the browser ratio is less than our image ratio then multiply the browser width by the ratio to acheive the width of the image. If we used just one of these to get our width then if the browser was long and skinny there would be a big gap at the top and bottom of the image. If our browser was short and fat then there would be gaps left and right. The only way to really see this is by commenting out the two sections individually. First comment out the else and then the if.
The final part of the resize function is to make sure the image always stays in the centre of the screen (lines 36 and 37).
$(this).children().css('top', (browserheight - $(this).height())/2);
By using $(this).children() we are going straight to the image inside the div. We are changing the left and top properties of the image to take into account the width and height of the browser. By subtracting the image width from the browser width and then dividing that by two we know what the left property should be and then the same with the height to find the top property. The left property will always be zero until the browser ratio increases above the original image aspect ratio.
All that is left for us to do is to attach the supersize() function to the div with the background image. We do this once the DOM has loaded:
$("div#supersize").supersize();
});
If you have any questions about the code then please don’t hesitate to leave a comment or contact us via our contact form.
Beautifully explained and very useful to know. I am sure to be using this in one of my upcoming websites !!!
Thanks team Grow – you are awesome
Raphael
Beautiful. Thanks!
Lovely site design! I discovered your site via a jQuery Twitter post. I’ve been looking into full-size scaling backgrounds. You have adapted it wonderfully–especially the way the site content sits over the top so nicely. I’ve been having a few issues with that, so nice to see your version.
I really like your blog and i respect your work. I’ll be a frequent visitor.
nice, thanks! I also found your website via jquery twit. your website design as your example is very beautiful
Glad to hear that the post is useful. Thanks for the comments. Please let us know if you have any questions.
Very Useful. Thanks
I like this!
I’m a big fan of background images, so this will be used by us in next projects
Great, but the scripting is really not necessary. You can achieve the same effect with only XHTML and CSS, still be standards-compliant and still work cross-platform.
You also get the option to preserve the aspect ratio – or not, depending on the image.
I documented this on my blog: http://blog.urbanmainframe.com/2009/05/create-a-dynamically-resizing-background-image-using-css/
Might be useful to you.
Hi Johnathan
Thank you very much for the reply.
I checked out your XHTML and CSS version and it is great.
Thank you for sharing.
No problem guys. Thank you.
Script doesn’t work with opera, I always get the scrollbars.
Tested in OS X and Version 10.00 and no horizontal scrollbar but #h1 and #tagline collapses when you vertically scroll
thanks !
Good work! I have been searching for this kind of script that would work seamlessly.
I would use this for future projects.
Keep it up!
TNX for sharing.
Guys, thanks for this. I was working on this very problem when I came across. You saved me a few hours. One improvement would be to make the script autodetect the image size.
2
var startheight = $("#supersize img").height();
Cheers!
@The Sheraz
Great addition to the script.
Thank you.
Is there a posibility to have slideshow option like in supersized script?
@Jere Paajanen
The way to add a slideshow option would be to use the Supersized plugin for jQuery. It is very simple to use. We have added the link in the reference section of the post.
Nicely written! I will be coming back for more
Very nice !
Also I had to add “position: relative” to each div displayed hover the background to make links and selection workable
Simple and elegant! And semantic..
Shame is does not work in Ie6.
I just spending my 1 hour to learn this and implement it into my background image slider [4 background pictures], and this script was working awesome, but, one thing i want to ask…
how to fire this :
2
3
$("div#supersize").supersize();
});
to my buttons, because I found out that, the rest of images [2nd, 3rd, and 4th] are not affected when I click to slide, because the function only run once for the 1st image…
please help me out with this…
i love this script
thanks
I like the addition of the jQuery to the CSS style. A full browser background image opens the door of all sort of jQuery effects. Coming from an AS3.0 background, this help bridge the gap from interactive to static. I am using one of such effects on a site currently. Using the timer event, different images load randomly.
does not work for me
when i add css code, image just disappear.
Thanks so much for sharing this! I was afraid I was going to have to figure it out on my own.
Awesome site.
Great tutorial, works great!
How did you manage to get the file size down to 100k on the grass.jpg while maintaining good image quality?
Hi guys, I really like your approach as I have implemented the GotoChina example on my website. I have started redoing my website using your example to resize images rather than resizing them to fit myself.
The problem I am experiencing is that this does not work on IE8 if I put it into IE8 mode using IE Developer toolbar.
I notice you are setting your page using:
Did you encounter this problem and therefore set IE to always emulate IE7 mode?
I would like to fix this so if you had any ideas that would be great as I have already dredged the internet searching for answers to no avail.
Thanks again for your great solution.
Often, we see how libraries are used inappropriately JS (Framework) to achieve effects that are possible with very few resources. Alternatively, I propose a solution in pure HTML. Here:
2
3
4
5
6
7
<head>
</head>
<body bgcolor="#FFFFFF" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" scroll="no">
<img src="img.jpg" boeder="0" width="100%" height="100%">
</body>
</html>
Greetings.
Un Saludo.
Thank you @The Sheraz!!
Hi, thank you for this great toutorial.
For a project i’m looking for a solutionto to combine yours with with random background images on reload. I tried several ways but it dosen’t work. Maybe you have an idea, that would be very nice
.
Thanks allot
Martin