How to Implement Background Video

Posted in Tutorials

Tweet This Share on Facebook Bookmark on Delicious Digg this Submit to Reddit

There is currently no such thing as CSS background-video like you have for background-image.   What you really have is regular HTML video using either “position absolute” or “position fixed” so that it is taken out of document flow. Then elements are placed on top of it, or it can be moved underneath with z-index.

So you get something like this…


If you want to jump to the chase and just view the full code, scroll to the bottom.

Part 1: HTML setup

Let’s start off with HTML of a “video-container” and a “tagline” element within it…


And you get something like this with the lightgray area being where the video will be occupying …


We used the centering technique in the last tutorial to center the tagline within the center of the video-container.  We fixed the video container flushed to the top, left, and right borders of the browser.  We set the video to be always at a height of 400px.

The problem is that if you have “main-content” following…


It will be hidden underneath the video-container, unless you margin-top the exact amount that the video-container covers …


Part 2: Converting our video

Now we are ready to put in our HTML 5 video — IE8 is not supported (see  You can find background videos as mentioned in the Sitepoint article or, or various searches.   For the example in this tutorial, we use the free space background video found on here.  Unfortunately it is in mov format.

Checking media format support, seems like mp4 is most supported by browsers.  To be cross-browser compatible with older browser, you might want to include ogv, and webm as well.  Like this …


So we rename and convert our .mov file to those indicated above using ffmpeg by following instruction here.

Taking a look at the size of our output video …


we see that our MP4 file is 3MB (which is too big, probably because the original .mov video of mov is 59MB large).  At this point we should go and find a smaller video so ideally users should not have to download a video bigger than 1 to 2 MB.

But we keep these for the purposes of this example to demonstrate the problems of slow connection and large video.

Part 3: HTML5 video tag

Consulting with the HTML5 video tag reference, we set the video to be autoplay, loop, and muted…


Now when you render the HTML page, video should play locally or on web server…


Part 4: Server MIME Types

If it does not play, you may have to edit the “mime.types” file in “/etc/apache” or use the “AddType” configuration directive in httpd.conf as noted in the above reference.   Especially if you are trying to play the ogv or the webm version.

Part 5: Video height

Another problem we see is that this video height is too tall and the height attributes of 400px in our video container is not being respected.  We can pick another video with a better height ratio, or we can use the height attribute on the video tag …


Now we can now see the text underneath, but the width of the video is wider than viewpoint, causing horizontal scrollbar at the bottom….



It is not responsive and not respecting the width of the container.  Looks like we need to set the width attribute of 100%…


Now the video conforms to the browser width, no more horizontal scroll at bottom…


But there is black space above and below the video in the attempt by the browser to accommodate the height of 400px.  In the case of this video, it looks fine.  But in other case, it might not.

While a possible solution is to use Javascript to adjust the height parameter of the video tag and video container dynamically as the browser width changes.

A better solution is to use height auto on video tag and video container.  …


This will be fine if you don’t have content after it.  But if you do, it looks like this …


We have to remove the 400px margin-top on the main-content …


But now our video (because it is absolutely positioned), covers up our content.  We need to put video back into document flow if you want our main-content to automatically follow below it….



This works, except our tagline is not absolutely positioned to the document body instead of video-container…


Unless we add position relative to the video container…


Now it works …


Part 6: Video Poster

On slower connections, you can see the lightgray background of the video-container while the video is being loaded.   We can add an initial poster image to the video tag.  For extra measure if you want, put that as the background-image of video-container as well.

We should make the poster image the first frame of the video (and also the same size) so that when video does play, it appears to transition seamlessly…


Although it is not really necessary, and we don’t want user to download two posters.  So we remove the background poster from video-container.

Part 7: Javacript play when ready

On even slower connections, to avoid choppy playback, you want the video to play only after it has downloaded enough first.  In this case, we remove the autoplay attribute from the video tag and use Javascript (in an IFFE at the bottom of the file) to detect when “canplay” or “canplaythrough” event are triggered…


But at the time of this writing, my Firefox 44 on Windows 10 doesn’t play the video with this Javascript, even after adding additional check for readyState (in case video is cached and canplay is not triggered)….


So we’ll put back the autoplay on the video tag and remove the Javascript.

Part 8: Video Controls

This starfield video example is one example where video and be disorienting to users.  After looking at it for a few seconds, I’m getting dizzy.  Also there are people with photo-sensitivity. So you need a way for them to pause the video.

The easiest way is to add controls to the video via the controls attribute …


The look-and-feel is browser dependent …


Part 9: Do not autoplay on mobile

At current, mobile devices will not autoplay video (even if you have the autoplay attribute) for fear that it would rack up large data charges.  Therefore we add media query for viewports less than 800px wide to hide the video with display none.  And add background image to video-container.  Because video is no longer there to prop up the video-container, we add a height of 200px…


Keep in mind that the video file is still downloaded on mobile even if display is none.

10.  Stop Looping Forever

While we have not done it here, it is a good idea to stop looping forever by using Javascript timer to call video stop.

The full code…

The full HTML …


The full CSS …



Some good reference tutorials by Nick Salloum and by Dudley Storey and Sitepoint article.