Random background images with CSS background-size

So you want to display background images on your website?.. Coincidence – me too! Firstly why not pause for a second and refresh this web page for a while and appreciate the lovely photography :P

Mac OSX, Safari 5.0 screenshot

Mac OSX, Safari 5.0 screenshot

If you’ve tried background images (unsuccessfully) in the past, no doubt you’ve come unstuck with a few of the same sorts of dilemmas as I have: the first culprit being content vs. image legibility, and the second being each image’s responsiveness to the viewport (will the image tile or stretch?; in which case you have to start thinking about tessellation accuracy and file size etc.).

Enough!! I hear you cry! I don’t want to have to think about any of this stuff. True, true.

I was lucky enough to come across an article on CSS variables recently. The main spark I took from this article was the capacity to link to a PHP file, just as if you would any normal CSS file. Not only does this help keep our code modular; more importantly this affords us access to variables like any conventional PHP-processed file does. Once the file loads we change the content type back to CSS by using the PHP header() function:

header("Content-type: text/css; charset: UTF-8");

Are your fingers itchy now? Yea, thought so :P


  • Scale width and height proportionally depending on variable viewport dimensions
  • Randomise on page visit or refresh (for added interest)
  • Cross-browser compliant (modern, A-Grade)
  • Not impact performance/load time too much
Mac OSX screenshots (… continued)
Mac OSX, Opera 10 screenshot

Mac OSX, Opera 10 screenshot

Mac OSX, Firefox 3.6.8 screenshot

Mac OSX, Firefox 3.6.8 screenshot

Mac OSX, Chrome 6.0 screenshot

Mac OSX, Chrome 6.0 screenshot

PC Windows (XP) screenshots
PC Windows XP, Safari 5.0

PC Windows XP, Safari 5.0

PC Windows XP, Opera 10

PC Windows XP, Opera 10

PC Windows XP, IE8

PC Windows XP, IE8

PC Windows XP, IE7

PC Windows XP, IE7

PC Windows XP, Firefox 3.6.8

PC Windows XP, Firefox 3.6.8

PC Windows XP, Chrome 5.0

PC Windows XP, Chrome 5.0

Selecting suitable images/photos

Before you crack open the text editor though, there are a few things to bear in mind when you’re selecting those choice snaps:

  1. Type (content)
  2. Size/dimensions
  3. Aperture and point of focus
  4. Colour and mood
  5. Texture



The only major benefit of linking to the file, as opposed to building our script directly in the header, is that we maintain modularity. If you want to delve further, there exists further discussion on the pros and cons of linking to PHPCSS here. ATTENTION: I’d be grateful if any PHP experts out there would provide clarification on this issue for the purposes of this article – comments welcomed.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<link href="scripts/php/bgImages.php" media="all" rel="stylesheet" type="text/css" />


As mentioned above; here we change the content type back to CSS by using the PHP header() function:

// PHP/CSS variables / Thanks to: http://css-tricks.com/css-variables-with-php/
// Set the Content-type back to CSS:
header("Content-type: text/css; charset: UTF-8");

In case you’re wondering why there’s a bunch of Flickr URLs below… I decided it was probably cheaper (bandwidth-wise) to purchase a Flickr Pro account and use it as a CDN for images in the future. Doing it this way also makes my script a little more portable and simplified, as I don’t have to worry about mapping (which can sometimes be tricky when working inside WordPress).

// Get domain URL
$domain = $_SERVER['HTTP_HOST'];
$domain = 'http://' . $domain;

// Set up array of bg images
$bgImages = array(
// Randomize array
$random = array_rand($bgImages, 1);

Lastly we grab our images using CSS – complete separation of style and content. Notice the use of a CSS3 background-size property:

body {
background:url() 0 0 fixed no-repeat;
body[class*="opera"] {
background-size:100% auto; /* No support for background-size:cover, no -o-background-size prefix, thank God for WordPress (K2) body classes! */

The use of the ‘cover’ background-size value, gives us one major advantage over a more conventional value like: 100% 100% (height and width size dimension respectively):

[The ‘cover’ value] specifies that the background image should be scaled to be as small as possible while ensuring both its dimensions are greater than or equal to the corresponding dimensions of the background positioning area.

developer.mozilla.org In yiddish: the image will always keep its native proportions AND fill the screen without tiling or distorting its shape. You can experiment yourself by resizing your browser window.

Cross-browser compliant (modern, A-Grade)

Support is, on the whole, great. Even IE (including IE7) doesn’t appear to kick up a fuss.

However, while Opera supports the vanilla CSS3 background-size property (yay!), unfortunately it doesn’t accept the ‘cover’ value (boo!). Fair enough, we can use the ‘100% auto’ example they provide in their demo, along with a browser prefix to target, right? Wrong: Opera made the -o-background-size property redundant, so our only solution is to target using a body class.

Thankfully for me WordPress K2 has browser detection as standard, but others might not be so fortunate. To my knowledge WordPress Twenty Ten doesn’t.


If you know of a more suitable solution drop a comment below


As you may expect there is very slight performance lag when opting for the ‘cover’ value, and page scroll suffers too slightly, as the browser works to keep your images in shape. Also be vigilant of using the ‘repeat/repeat-x/repeat-y” value anywhere in your background properties. If you’re sizing your images with the ‘cover’ value then there’s no need to tile repeat in any direction.

13 Responses to “Random background images with CSS background-size”

Leave a Reply

ATTENTION: Feel free to use HTML - all the important tags should work. Please wrap your scripts in <code>...</code> - thanks!