Wednesday Aug 6, 2025
The Smooth Fade-In: Animating a Random Background on Page Load
I am still working on the Discontinuity Studios website. I came across an interesting problem I worked around and would like to share.
The Problem
I want the background graphic behind everything to change each time the page loads and fade in smoothly.
The First Solution
The first solution I came up with involved setting the body element up with a background.
body {
background-image: url('/img/backgrounds/1.png');
}
I tend to solve problems by breaking them up into little steps so I built the step that forces a random graphic change each time the page loads first. I set it up beforehand with some indexed graphics in a folder, and I want the JS to load a random background graphic from that folder each time.
My JS chooses a random number and then uses that to build the body's src attribute.
const totalImages = 10;
const randomNumber = Math.floor(Math.random() * totalImages) + 1;
const imagePath = `../img/backgrounds/${randomNumber}.png`;
const imgElement = body.style.backgroundImage = `url('${imagePath}')`;
That worked just fine. It blinks in a new image each time the page is loaded. Great.Now, to move on to build the fade-in. My thought was that using CSS transitions should be easy. I needed to set the transition on the body element's background image. Simple right.
body{transition: background-image 3s ease-in;}
I'll save you the webkit annotation.
That did not work.
I tried giving it a background-image initial setting, so the JS would override the background image using the local attribute.
Nope, no fade in.
The timing of loading the graphic and then animating that graphic using CSS transitions timing is funny. Hmm, an interesting problem to solve, but I don't have time for this. I needed a different solution, but didn't want to throw away all that working JS.
The Final Solution
The solution that worked. Instead of messing with the body, I chose to insert a DIV stretched across the entire viewport in the background of everything.
The HTML
div id="background-image"
The CSS
#background-image {
background-size: cover;
background-position: center;
position: fixed; /* Or absolute, to stay in the background */
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1; /* Place it behind all other content */
}
The JS
My JavaScript now looks like this.
const totalImages = 10;
const randomNumber = Math.floor(Math.random() * totalImages) + 1;
const imagePath = `../img/backgrounds/${randomNumber}.png`;
const imgElement = document.getElementById("background-image");
imgElement.style.backgroundImage = `url('${imagePath}')`;
gsap.from("#background-image", { opacity: 0, duration: 7 });
It chooses a random number, like before. Now it inserts that random number into the src attribute of our div element.
imgElement.style.backgroundImage = `url('${imagePath}')`;
I then use GreenSock JS to animate the fade-in on that same element.
gsap.from("#background-image", { opacity: 0, duration: 7 });
So, by inserting this one div into the HTML of my document, it will slowly fade-in a new background image each time the page is loaded.
It works so great every time the page loads that adding it to my snippet library is absolutely a good idea.