Color changing backgrounds are a pretty cool effect to have on your site if done correctly. And they also make for a neat little programming exercise for when you’re bored. Here I’m going to give a tutorial on how to implement a color changing background in jQuery.

Feel free to follow along using this fiddle I have prepared.

Step 1. Setup the page.

Lets just start out with a call to the ready function

$(document).ready(function(){
    // Here's where everything happens
});

If you are following along in jsFiddle, this is already supplied along with some css.

The first order of business is to think about how the background color is defined. The easiest way to do this is with RGB values. So we’re going to need 3 variables to hold each value between 0 and 255.

I’m going to define a function to do that instead of typing out the code 3 times. Since the rgb values will have to be put into string format before they can be used for manipulating css, it would be convenient to do that in this function too.

So my code now looks like this.

// Take RGB values and return a CSS formatted string representation.
function toCSS(r,g,b){
    return "rgb("+r+","+g+","+b+")";
}

// Return a pseudorandom number between 0 and 255
function rcv(){
    return Math.floor(Math.random()*256);
}

$(document).ready(function(){
    var r = rcv();  // variable for red
    var g = rcv();  // variable for green
    var b = rcv();  // variable for blue

});

The next step is set the background color, and figure out a way to make it cycle. So on the last line of the $(document).ready(); call, right before the closing }); , add the following line.

$('body').css('background-color', toCSS(r,g,b));

Now if you refresh the page, you should see the background color change to something random each time.

Step 2: Make the colors change

This part is a little more tricky. Making the colors change isn’t very difficult because all we really need to do is to add a function that slightly changes each color value, and then call that function periodically (lets start with every 50ms) in order to achieve a smooth transition.

To do this we can add this right below the $('body').css call.

var delay = 50;    // pause 50 milliseconds before changing the background.
function transition(r, g, b){
    var color = toCSS(r,g,b);                   // get the background color.
    $('body').css('background-color', color);   // and apply it.

    setTimeout(function(){
        transition(r+1, b+1, c+1);      // now increment the colors and call
    }, delay);                          // the function with the function with
}                                       // the new values.

The tricky part comes when we consider the fact that each color value can only go from 0-255. So if our function incrementally changes each color value, it has to be able to handle the restriction on the input bounds.

The immediate solution I jumped to was using the modulo operator. However, after a little consideration I came to realize that this would enable smooth transitions, only up until a color value reached 255. Then there would be a sharp change as that particular color jumped back down to 0.

Step 3: Make the colors change…better.

To address this lets just look at some nice mathematical properties.

Namely the properties of -1^n when n >= 0. The function f(n)= -1^n will oscillate infinitely between 1 and -1, which can be used as an indicator for which direction the color value is changing. As long as we want to stay out of trouble, n should remain an integer. So if we modify the function slightly to consider both the 0-255 range, and the integer constraint, we get something like f(n) = -1^(Math.floor(n/255)).

As you can see, this function will remain positive for the first 255 values. This models the initial incremental motion of the color values. Once the input is greater than 255, the value shifts to -1, indicating the change in direction as the colors begin to descend from 255 back to 0.

With this in mind, we can add a helper function that takes in any value (0-infinity), and returns a value between 0 and 255 taking oscillation into consideration by first determining whether the direction is positive or negative using the -1^n method, then either returning that value mod 255, or returning the difference between the 255 and the former.

function colorValue(n){
    var dir = Math.pow(-1, Math.floor(n/256));
    if(dir==1){
        return n%256;
    }
    return 255-(n%256);
}

Now we can substitute the arguments in the toCSS function call with values returned by this function.

function colorValue(n){
    var dir = Math.pow(-1, Math.floor(n/256));
    if(dir==1){
        return n%256;
    }
    return 255-(n%256);
}

var delay = 50;    // pause 50 milliseconds before changing the background.
function transition(r, g, b){
    var color = toCSS(colorValue(r), colorValue(g), colorValue(b));
    $('body').css('background-color', color);

    setTimeout(function(){
        transition(r+1, g+1, b+1);
    }, delay);
}

Step 4: Make it go.

Now we just add a call to the transition function from within our $(document).ready(); function, and pass in the r,g,b values that were defined previously.

var r = rcv();
var g = rcv();
var b = rcv();
$('body').css('background-color', toCSS(r,g,b));
transition(r,g,b);

Voila. You should see it run.

Here’s the full script.

// Take RGB values and return a CSS formatted string representation.
function toCSS(r,g,b){
    return "rgb("+r+","+g+","+b+")";
}

// Return a pseudorandom number between 0 and 255
function rcv(){
    return Math.floor(Math.random()*256);
}

function colorValue(n){
    var dir = Math.pow(-1, Math.floor(n/256));
    if(dir==1){
        return n%256;
    }
    return 255-(n%256);
}

var delay = 50;    // pause 50 milliseconds before changing the background.
function transition(r, g, b){
    var color = toCSS(colorValue(r), colorValue(g), colorValue(b));
    $('body').css('background-color', color);

    setTimeout(function(){
        transition(r+1, g+1, b+1);
    }, delay);
}

$(document).ready(function(){
    var r = rcv();  // variable for red
    var g = rcv();  // variable for green
    var b = rcv();  // variable for blue
    $('body').css('background-color', toCSS(r,g,b));
    transition(r,g,b);
});

Not too bad huh? All you gotta to do make it work is add a script tag to the page you want it on, and point that at this script.

Here’s the full fiddle if you’d like to see.