CSS trick – two background images

While using what I’m sure is my own idea of progressive enhancement on a web page, I came across an interesting situation: I wanted two background images, rather than one. My first background would be a general tiled image, to give the site’s background a nice texture; the second a vertically-repeated image on the left-hand side, to be used in conjunction with a floating nav menu.

Now, while CSS3 is purported to support up to 8 background images — no doubt to make rounded corners and other fancy borders easier for coders — the problem is that, to the best of my knowledge, IE and FF don’t yet support this feature. Besides that, IE6 and lower never will. And I’m not even sure this feature will be usable for what I want, anyway.

So, I had to have (ok, really, really wanted) the left-hand background, and, IMO, the page looked too bland without some texture on the general background. As I already had the structure of the page decided upon (and, as such, couldn’t modify it for presentational purposes), I started looking at what I had to work with. There was obviously the body tag, but there was nothing much else to work with…besides the html tag itself.

I already had the vertical background applied to the body tag, so I started by removing the background color from body (so the html background could show through). I then applied the same background color and the new background image to the html tag:

html {
    background: #000 url("tiled.png");
}

body {
    background: url("vertical.gif") repeat-y;
    background-position: 75px top;
}

And, whaddaya know, it worked! Unfortunately, it seems that declaring the html element’s style in my CSS changes the basic behavior of the body element, making it more like a containing div. The result: there’s a margin around the content, and the vertical background only goes to the end of the content. Yuck.

So, the first thing to do is fix the ugly margin. Easy enough: set body’s margin to 0 , as well as body’s padding for good measure. Next, fix body’s background. Currently, the background stops at the end of the content area. Not a problem if the content causes the window to scroll, but not pretty if there’s not enough content. I figure this should be easy enough to fix, just set body’s height to 100%. This works well enough…in IE6. Strangely, FireFox 2 doesn’t take so kindly to it. Changing the body’s height to “auto” works alright, for both browsers, for overflowing content, but not for short content. A height of “auto” and a min-height of 100% works excellently in FireFox 2…but, again, IE6 doesn’t know how to treat min-height. Good grief.

So, I enter the realm of CSS hacks. Using a min-height hack combined with advanced CSS selectors that aren’t understood by IE6 and less, I combine the methods that worked for each browser into a series of rules that are “browser-filtered” – one browser uses one method, while another browser uses the next.

html {
    background: #000 url("tiled.png");
    /* Height is 100%, so the body can be 100% */
    height: 100%;
}

body {
    background: url("vertical.gif") repeat-y;
    background-position: 75px top;
    margin: 0;
    padding: 0;
    /* Height is 100%, so the tiled BG will tile all the way down
       the page, not just as far down as the page's content
       (when the content's height is less than the window's height) */
    height: 100%;
}
/*
Hackety-hack-hack...
FF2, with the above code, will only display the repeat-y image for as
    high as the window's viewport is; higher content (upon
    scrolling) will not have the bg.
This "hack" makes the tiled background work properly in FF2.
This type of "advanced selector" is not understood by IE6...dunno
 'bout IE7.
*/
html>body {
    min-height: 100%;
    height: auto;
}

The common html code works fine on both browsers. It’s only the body’s height issue that needs resolved. The IE6 code is given in the body code; both browsers will see this and understand it. However, when they get to the html>body statement, IE6 says “wha??” and drops the rule, whereas FF2 says “ok…” and applies the appropriate styles to the body tag, overriding the earlier-mentioned height.

View the live example or browse the files

This post is rather consistently my most-read post on this blog. If you found the information in this article useful, you may want to check out some of these related articles here on TechKnack:

42 Comments:

  1. I Andrew, i like your post. Very usefull for me. Thanks… greeting from indonesia..

  2. I’m glad you found it useful :D

  3. Nice article :)
    I, too, have experimented with using the BODY and HTML elements more effectively. If you’re interested, check them out here and here.

  4. I wrote about this in 2004 – check it out

  5. Great post. Thanks for sharing your expertise.

    I’m curious. Was there a reason for adding the padding-bottom to the body?

    I’m on a mac so I haven’t seen this on IE yet, but it appears to work fine without it.

  6. Thanks, Josh, glad you liked it.

    I’m afraid the padding-bottom:1em; is legacy code from my own implementation (which I obviously forgot to remove…oops). I used it to keep the page footer from being flush against the bottom of the page, which is where it was ending up when the content caused the window to scroll.

    I’ll go ahead and remove it, to avoid confusion ;) Thanks for bringing it to my attention!

  7. thanks so much!!!!!

  8. The technique seems intriguing, but I wish there were an example included. Am I just missing a link to an example somewhere in your article?

  9. cakins: I hadn’t considered putting together an example, the main reason being that I have no hosting other than blogspot :) . I’ve now put a little something together using box.net, and put a download link to it in the article; you weren’t missing anything ;)

  10. I have been updating/making my blogger page stand out and as such, I made my own illustrated bg image for my blogger site. Unfortunately, I made the image the right size for my own browser/resolution but when shown on pretty much every other computer, the image is cut off in some place, or even too small on others.

    I was wondering if this would work for what I would like to do, which would be dividing my bg image into two, right and left, and attaching them to their respective sides of the window. This way, in theory, no matter the size of the window the image would be fixed and the proper size.

    I tried defining two backgrounds, the urls in the same place, separated by commas like I saw here but it… didn’t work. :T

    Here’s my blog link, by the way.

  11. Ooh – never thought to try this :) . Thanks for the tip!

  12. Thanks a lot for your great work! You saved me a lot of time.

  13. Katelynian, I can’t believe I missed your comment! So sorry.

    The comma-separated-values usage is a CSS3-only feature. As such, I believe the only major browsers to support it are Safari and Konqueror (if memory serves correctly). I think FireFox 3 and possibly Internet Explorer 8 will support the multi-background feature (as adept at passing Acid2 as they are), but I’m not sure.

    Anyway, you could probably split the image, like you said, and use one image for each element. This would, in effect, be what has been termed the “Sliding Doors” effect, an effect that has been used in navigation tabs for a long time now. More on the technique at AListApart and Google. Just make sure your images have plenty of horizontal overlap for larger resolutions!

    On a second look at your blog, it looks like you figured something out :) looks good, though there is a 40px gap when I maximize FireFox on my 1440×900 resolution screen ;)

  14. awesome. thank you!

  15. Extremely useful! Big kudos!

  16. a gem of css. thanks!

  17. Thank you very much :* you saved my nerves, I spent two days on it, trying to put 2 images in background, the difference between my and your code is that I put image on body, and it worked only without doctype specified..How I didn’t think about html…?

    Thank you very much :* muoa muoa muoa

  18. thank you!!
    i’ve been looking for a little help on this ^^

  19. This isn’t working for me :( browser only displays one image or the other…not both. Any ideas?

    http://www.cenlamedia.com/kalb/chg/

    style sheet linked

  20. OK…I’m officially an idiot. Once I put the Doctype at the top of my html, it magically worked :)

  21. Ooo my god!!!! Thank you sooooo much =D

  22. Nice thinking putting styles on the element.

    I don’t see the difference though if you were to just put a tag within your – since the tag starts acting like a once you’ve styled the tag anyway. It would seem to me to be a bit cleaner / standards-compliant too – but I’m no authority on that.

  23. Thanks for this fix, i\’ve been trying to get this result for hours.

  24. Thank you so much for the help, this tutorial really helped me with my layout, especially the margin:0 part! I wouldn’t have worked it out without your help :)

  25. Thanks for the wonderful post. Quite helpful.

  26. Wow, this is the exact thing that I am trying to do right now! Thanks so much for the help. I knew there must be some way of doing this :D

  27. Thanks so much for the tip!!
    It is really useful for me :)

    because I am making a website for my society, and want to make a banner on top left corner and a background image on the right bottom..works so fine now..was looking for so many solutions, urs works immediately, thank you so much!!

  28. This is exatly what i need! Thank you very much!

  29. Pffff i need to place a BG all over the site, but place another at the absolute bottom of the page… with width of 900px think you can help me out ?

  30. don\’t reply to this i\’ve finally made it ;)

    http://www.god-makers.com/index.htm look at the bottom pic and the regular BG… thanks a lot man !

  31. Try this!!!
    CSS
    .right
    {
    position:fixed;
    right:0px;
    z-index:-1;
    bottom: 0px;
    }
    .left
    {
    position:fixed;
    left:0px;
    bottom: 0px;
    z-index:-1;
    }
    HTML
    This will show a image on the right-bottom side
    This will show a image on the left-bottom side

  32. Opss!!!

    image code, don forguet “”

    img class=”abajoder” src=”Imagenes/fondo-der.gif”
    img class=”abajoizq” src=”Imagenes/fondo-izq.gif”

  33. Perfect! Exactly what I was looking for! Thanks!

  34. Thank you thank you thank you! Saw something like this on http://www.starcraft2.com/ and wanted to figure out how to overlap backgrounds. beautiful!

  35. Thanks. It helped! :)

  36. Been trying to figure this out for ages! Thanks a lot!

  37. Hey,
    I just wanted to thank you for the margin: 0; part, as it made mine work and was the part I was missing.

    user

  38. Hey thankyou so much! your tip really worked… I was struggling from 2 days to fix a background! Thanks again!

  39. thank you so much for the tip! i managed to use it with my blogger layout~

  40. Totally awesome, thank you! :) I’m using this for my website.

  41. okay so basically i have a poblem, my bacground picture for my site is too big so it load very slowly, i want to make the picture into two then join it with html coding but does any of you know how to do this withough messing up the picture if you can would you please post a code or even send me one please and thanks you.

  42. Awesome guide, thanks! :)

No Pingbacks