loading...

Fading in a video background in React is fun!

ma5ly profile image Thomas Pikauli ・3 min read

Using a video as a background is fun. It allows for captivating website design. Unfortunately videos are on the heavy side of the MB spectrum, which means they take a bit more time to load than your HTML, Javascript and CSS. As a result the video might suddenly pop up in the background after your visitor already has settled into the website, slightly ruining the elegant effect it's supposed to have. To solve this we can use a short fade-in on the video.

Fading in a video

To fully appreciate the effect, see it live in action here

We're going to do this in React, since Gatsby is quite popular (rightfully so), but it shouldn't be much more difficult in plain Javascript; if not easier. Let's start with the video itself. If you have a React component, you can drop in the video tags in your JSX.

class MyCoolWebsite extends React.Component {
  render() {
    return (
      <video
        autoPlay
        muted
        loop
        style={{
          position: "fixed",
          width: "100%",
          left: 0,
          top: 0
        }}
      >
        <source src="urlOfMyVideo.mp4" type="video/mp4" />
      </video>
    );
  }
}

You might notice I added a bit of inline-styling to make the video appear across the entirety of the screen. You can change this styling to whatever fits for you. Also there are a few video attributes, which respectively make the video play automatically, mute the sound the video might have, and loop it into eternity. Next up we add a ref on the video element.

    return (
      <video
        ref={ref => (this.video = ref)}
        autoPlay
        muted
        loop
        style={{
          position: "fixed",
          width: "100%",
          left: 0,
          top: 0
        }}
      >
        <source src="urlOfMyVideo.mp4" type="video/mp4" />
      </video>
    );

The thinking here is that once the component is mounted, the video is going to start loading, which means we somehow need to hook into that process. The ref we just placed helps us with that. We can access it, and then we can add an event listener to it.

  componentDidMount() {
    if (this.video) {
      this.video.addEventListener("loadeddata", () => {
        // execute code here
      });
    }
  }

  componentWillUnmount() {
    if (this.video) {
      this.video.removeEventListener("loadeddata", () => {
      });
    }
  }

This specific listener will execute a piece of code after the video has loaded, which is exactly what we need. And just to keep things neat and clean, we also remove the event listener once we don't need the component anymore.

Now for the fade-in itself. The way we will set this up, is by using a bit of CSS that changes upon the video being done loading. To be more specific, we will initially set the video to an opacity of 0, and then once it's done loading, we'll set the opacity to the default of 1. The transition property will turn this into a slow fade (depending on how many seconds you set it).

But before we do that, we first need to make our styling aware of the loading being done. We can utilize state for that. As you hopefully remember, we just set up an event listener. In that listener we're going to change our default loading state which I had set to true.

  state = {
    loading: true
  };
  componentDidMount() {
    if (this.video) {
      this.video.addEventListener("loadeddata", () => {
        this.setState({ loading: false });
      });
    }
  }

With this in effect we can hook up the styling we just talked about. The most interesting part is obviously the opacity property, which has a ternary operator to dynamically change the opacity based on our component's state, which in turn reflects the video's loading state. I do hope that makes sense.

    return (
      <video
        autoPlay
        muted
        loop
        style={{
          position: "fixed",
          width: "100%",
          left: 0,
          top: 0,
          opacity: this.state.loading ? 0 : 1,
          transition: "opacity, 2s ease-in-out"
        }}
      >
        <source src="urlOfMyVideo.mp4" type="video/mp4" />
      </video>
    );

So with that in place we're about done. You can now set a regular background in your app, and then have the video background fade over that background after it has loaded. Quite a nice effect, I hope you make something beautiful with it!

Discussion

pic
Editor guide
Collapse
barrbozzo profile image
Constantine

Awesome!

Collapse
alfredrafael profile image
Alfredo Rafael Pabon

Awesome! Thank you