Making a full body background "slideshow" for your web page
Tags: html, css, javascript, slideshow
Published: 2023-08-11 11:05:39

If you are a business with a landing page, having a slideshow of images as a background of that page can lend a lot of character to it. It can serve as the right accent for the other content you have in the foreground, not to mention it's a lot more fulfilling and enriching (at least to me) to see background images rather than a plain, solid background.

Back in the days of nascence of HTML, and before CSS took over the styling department, we would do this with the `background` property of the `body` tag, like we used to use `bgcolor` to set background colors. At the time of writing this, both of these attributes are deprecated and possibly awaiting removal (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body). That historical note aside, here's how we would assign a background image to a web page. We do that by styling the whole `body` tag.

```css
body {
  background-color: #222; /* to server as "filler" */
  color: #fff;
  font-family: "Fredericka the Great", serif;
  padding: 0;
  margin: 0;
  height: 100vh;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
```
>1. _Fredericka the Great_ is a [Google Font](https://fonts.google.com/specimen/Fredericka+the+Great), which I have included separately through a `link` tag inside the `head` section.
>2. You'll see that I am manually setting the margin to zero. This is because on most browsers, the `body` tag is rendered with a default margin of 8px.

Also, I feel like this is an important time to point out that what I am building is not _technically_ a slideshow, as in, there will be no sliding transition, rather a fading one (we'll soon see how). Regardless, I promise it'll still look cool.

First, let's store the image URLs in an array like so:

```javascript
const images = [
    // URLs
]
```
Next, let's add the necessary JavaScript code to load the images.

The first image can be loaded as
```js
document.body.style.backgroundImage = `url(${images[0]})`
```

Now, we can load the remaining images in loop, with the `setInterval` function:
```js
let i = 1
setInterval(() => {
  document.body.style.backgroundImage = `url(${images[i++]})`

  if (i === images.length) i = 0
}, 7000)
```

Finally, we add the following transition to the CSS of the `body` tag:

```css
transition: background-image 1s;
```

This is fine for the most part, but if we want a more seamless transition, we can add a preloading trick with a hidden image tag. The idea is to load the next image silently in the background, so your browser can rest easy when the next image is actually displayed, giving the user the perception of instantaneous loading. So we add a new HTML tag and style it so -
```html
<img class="hidden" alt="preloading" />
```
```css
.hidden {
  display: none;
}
```

The code to complement the above would be somewhat like this -
```js
document.querySelector('.hidden').src = images[next_image_index]
```

Putting it all together, the whole JavaScript code looks like this -
```js
window.onload = () => {
  // preloading
  document.body.style.backgroundImage = `url(${images[0]})`
  document.querySelector('.hidden').src = images[1]
  let i = 1
  setInterval(() => {
    document.body.style.backgroundImage = `url(${images[i++]})`

    if (i === images.length) i = 0
    else {
      // preload the next image, so that it transitions smoothly
      document.querySelector('.hidden').src = images[i]
    }
  }, 7000)
}
```
And as always, here's the sandbox. Enjoy!
{% codesandbox happy-mirzakhani-48zz2x %}

> Note that this is just one way of preloading images. The `<link rel="preload" ...>` tag, if present in the HTML, will also do the same. Also, some modern frameworks like Next.js feature auto-preloading of some assets.