Use Dropbox and Javascript for Better Videos in Weblfow

Are you working on a project and the native Webflow background video element isn't enough for you? Perhaps your client wants a full screen video and Webflow compression makes it grainy and ugly. Or it’s possible that it's an explainer video and sound is VERY important to the user experience. The Webflow element is extremely limiting for the following reasons:

  1. Maximum file size of 30 MB
  2. No audio allowed
  3. Restricted to the Webflow video player which has only play/pause on click functionality

With a little bit of knowledge of online file management and some custom HTML and Javascript, we can get around these restrictions to make websites with beautiful videos. This blog post will focus on completing three tasks:

  1. Host video externally on Dropbox - We'll need a direct download link for that!
  2. Use the HTML <video> tag inside an Webflow embed to drop out code into our project.
  3. Write some Javascript to control video playback

** I will be pulling most of the code and instructions for this from my FREE resource library - be sure to get yourself a copy.

Hosting Video on Dropbox.

  1. Compress your video file to 1080p 30fps with the Optimize for web box ticked. I like a program called Handbrake and was able to reduce a 220MB 1:30 length video to 76MB!
  1. Log in to or create an account with Dropbox
  2. Upload your video file and create a share link. It will look like this: https://www.dropbox.com/s/40d9bx2w61bn/sizzle%20reel%20chicago%20compressed.m4v?dl=0
  3. Change the www.dropbox.com part to dl.dropboxusercontent.com.
  4. It will now look like this: https://dl.dropboxusercontent.com/s/40d9bx2w61bn/sizzle%20reel%20chicago%20compressed.m4v?dl=0

Add The Video Into Webflow with the <video> HTML Tag and Style it to Your Liking

Add the following code to an embed on your page:

	<video class="wb-video-styles-controller" wb-embed="video" playsinline loop muted autoplay style="background-image: url('');" data-wf-ignore="true">
   <source src="URL-GOES-HERE" data-wf-ignore="true"/>
 </video>
  
  1. Add a div block and give it a class wb-video-styles-controller
  2. Wrap it in another div and hide that div so that wb-video-styles-controller doesn’t interfere with any click events. Or give it pointer-events: "none" with some custom CSS.
  3. Use this class to style your video element.
  4. I like the below settings for a nice full screen video (nest it inside a div with height=100vh)
.video-controller {
  position: absolute;
  left: 0%;
  top: 0%;
  right: 0%;
  bottom: 0%;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

Control Video and Audio on Click

Make sure this data attribute is on your <video> tag wb-embed="video" (If you copy/pasted from my HTML snippet you should be good to go.)

// Select all videos with data attribute wb-embed="video"
const videos = document.querySelectorAll('[wb-embed="video"]');

// Loop through all the videos
videos.forEach((video) => {
  // Pause on initial load
  video.pause();

  video.addEventListener("click", (event) => {
    if (video.paused) {
      video.muted = false;
      video.play();
    } else {
      video.pause();
      //video.currentTime = 0; // resets video back to start on click
    }
  });
});

Play/Pause Video only when video is in viewport

We will use the Intersection Observer API to determine when the video element is in the viewport and play/pause it accordingly. You can adjust the threshold value between 0 and 1 to control how much of the video must be visible to trigger the action.

// Create the observer for checking if video is in view
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        entry.target.play();
      } else {
        entry.target.pause();
      }
    });
  },
  {
    threshold: 0.2 // 0 (default) - element must be totally offscreen, 0.5 - 50%, 1 - element fully on screen
  }
);

// Select all videos with data attribute wb-embed="video"
const videos = document.querySelectorAll('[wb-embed="video"]');

// Loop through all the videos
videos.forEach((video) => {
  // Pause on initial load
  video.pause();
  // Watch for entering viewport
  observer.observe(video);
});