Learn how to use native HTML5 video, and implement it in the background of your site. All without using a plugin.
It’s 2016, and user interface and experience are more important now than ever. If you’re building a digital identity, whether it be for a website or application, “look and feel” plays an extremely important part. With Flash and third-party plugins, like QuickTime, making a rapid exit from the browser, and externally-hosted videos and audio tracks being hard to customize and implement the way you’d like, developers wanting to implement media may have been left scratching their heads a bit.
Luckily for us, media is making a big push into the limelight as native HTML5. We now have a host of different media types at our disposal, including video. Today, I’m going to show you how to use native HTML5 video, and implement it in the background of your site. All without using a plugin. We’ll take a look at some of the native video controls too, to make sure that a user’s experience is fully enhanced.
HTML5 video compatibility is really high. In fact, it’s supported in all modern browsers (> IE8). The inner workings of video, in general, can be complicated, especially when you start to dig into multiple formats, tracks, containers, and the works. I’ll spare you the change for this tutorial. What you should know is that when you’re implementing video on the web, you need to host three formats:
video
tag, initially consisting of VP8 video and Vorbis audio, and more recently VP9 video and Opus audioTo get your video formats in check, I suggest using the robust ffmpeg tool. If you just want to play around for now, then mp4 formats should do the trick. Using video in your HTML5 document is easy.
If the browser doesn’t support video at all, it’ll just ignore the source
tags and pick up on the placeholder text. Alright, enough theory. Let’s dig in.
Let’s imagine that we want to build a page with a full-screen background video. Let’s say it’s a landing page for your new product, so above that video, we want some heading text, some sub-text, and a call to action button. Pretty straightforward stuff right? Well, almost. We can’t quite have just one container with a background video in CSS, and the text inside that container. CSS doesn’t allow for video. What we can do though is some basic CSS trickery that’ll allow us to position our video absolutely in our parent container, breaking the regular flow of the document. Let’s take a look at what the markup might look like:
Welcome To My Product
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Suscipit qui voluptatum enim est deserunt assumenda, aspernatur quam aperiam, fugiat minus aliquam quisquam hic repudiandae nobis architecto ipsa numquam facilis nisi!
Now if we wrap this in an HTML5 doctype and load it up in a browser window, we’re going to see something pretty ugly looking. Don’t worry, we’re going to fix that. Let’s dig into some CSS.
Because we’re only using a few elements in this demo, I won’t use any CSS reset or normaliser. Let’s just write up our own:
html,
body,
div,
h1,
p,
a,
video {
margin: 0;
padding: 0;
}
On top of that, let’s get rid of the default font, and include Oxygen from google fonts.
Make sure to include the viewport declaration for responsive web design too. Our full HTML document should now look like this:
Background Video
Welcome To My Product
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Suscipit qui voluptatum enim est deserunt assumenda, aspernatur quam aperiam, fugiat minus aliquam quisquam hic repudiandae nobis architecto ipsa numquam facilis nisi!
Remember, we’re interested in a full screen video and viewport, so we need to make sure our html
and body
elements are full screen. Our base CSS should now look like this:
/* ============================================================================= RESETS ============================================================================= */ html, body, div, h1, p, a, video { margin: 0; padding: 0; } /* ============================================================================= HTML, BODY ============================================================================= */ html, body { height: 100%; } body { font-family: “Oxygen”, sans-serif; }
Alright, let’s move on!
We know we want our content layered, and that means we need to leverage z-indexing. Our content itself will exist in the normal flow of the HTML, but our video will remain fixed and in the background. Let’s start with that:
/* =============================================================================
CONTENT
============================================================================= */
.content {
position: relative;
z-index: 2;
}
/* =============================================================================
VIDEO
============================================================================= */
.video {
position: fixed;
z-index: 1;
}
Let’s add a little more style to our content so that we can forget about it and focus on our video. We’ll make that heading big and bold, and style the button a little bit too. I’ll just use some eyeball averages to get the content vertically centred, but there are other tricks (as we’ll see later). Here’s what I came up with:
.content {
position: relative;
top: 30%;
z-index: 2;
margin: 0 auto;
max-width: 720px;
text-align: center;
}
.content__heading {
margin-bottom: 24px;
color: rgb(39,39,39);
font-size: 44px;
}
.content__teaser {
margin-bottom: 24px;
color: rgb(89,89,89);
font-size: 22px;
}
.content__cta {
display: inline-block;
margin: 0;
padding: 12px 48px;
color: rgb(255,60,100);
font-size: 22px;
text-decoration: none;
border: solid 4px rgb(255,60,100);
}
Pretty straightforward stuff, but at least now there’s some visual appeal, which makes it a bit easier for us to work. Now, we have a bit of an issue with our video. Right now, it’s just pinned to the top-left of the screen, and if you’re on a bigger screen, it’s probable not occupying all available space. Let’s look at that.
There’s a nifty little trick floating around these days for maintaining a perfect vertical centre of an absolutely (or fixed) positioned element relative to its container. It leverages top
and transform
. The translation of an element by a percentage value is calculated based on the elements dimensions.
So if we nudge something 50% from the top of a container, then translate it back up a negative 50%, it will be perfectly centred. That leaves us with this:
Now, what about full-screening it? Well, we have to force that with a little bit of CSS again, using minimum widths and heights. Here’s the full CSS for the video:
.video {
position: fixed;
top: 50%; left: 50%;
z-index: 1;
transform: translate(-50%, -50%);
}
Now, we have a full screen video in the background! But wait a second…it’s not even playing. Let’s handle that now.
There are a host of attributes at our disposal, and you can view them all here. We’re only interested in three of them, but take note that by default, the controls are hidden from view. Because we’re trying to achieve something that’s purely aesthetically pleasing, we will keep it this way. The other three attributes we’re interested in are:
autoplay
– if specified, the video will automatically begin to playmuted
– indicates the default setting of the audio contained in the videoloop
– if specified, we will, upon reaching the end of the video, automatically seek back to the startAutoplay
is important, because we’re hiding the controls in the first place, and we want the video to actually play. Muted
is also important, and here’s why. It’s already a little bit intrusive to outplay a video and not allow a user to pause or stop it. But we can excuse ourselves a bit, because it’s all in the name of aesthetic value.
However, if we are auto-playing a video, we definitely want to mute it by default. Finally, there’s the loop
attribute. This isn’t really important so to speak, but just know that if you have a looping video clip, then this attribute takes care of that easily. Let’s add these three attributes to our video:
Hit refresh in the browser, and voila! You’re all done, and it looks beautiful.
We’re not considering something that I think is a bit important though, and that’s the fact that not everyone viewing your site is viewing it from a high-speed connection. Auto-playing an HD video on a slower connection can result in a jerky, unpleasant experience. Luckily for us, the video will by default show the first frame, giving users the appearance that it’s just a background image. With that in mind, we can present the video to the user with autoplay off, and play the video only when it’s ready. How do we do that though?
HTML5 video is under the “media” umbrella, and as such, there are many ways to interact with it, fetch data, and fire events. If we look at some of the methods available to us, we’ll pick up on the fact that we can actually play the video via the JavaScript method play()
. Also, if we take a look at some of the media events available to us, we’ll see two events of particular interest:
canplay
– sent when enough data is available that the media can be played, at least for a couple of framescanplaythrough
– sent when the ready state changes … indicating that the entire media can be played without interruptionYou’ll have to decide which one you’re going to use, but for now, let’s just stick with canplay
. First, we’ll remove autoplay
from our video:
Now, let’s interact with it using some very simple, but neat JavaScript:
(function() {
/**
* Video element
* @type {HTMLElement}
*/
var video = document.getElementById(“my-video”);
/**
* Check if video can play, and play it
*/
video.addEventListener( “canplay”, function() {
video.play();
});
})();
Pretty nifty, huh?
Now, it’s very important to note that media events and methods are very modern stuff, and browser support is scattered all over the place. But be mindful of all of this though, because it’s here to stay, and will only become more supported in the future.
For now though, make sure you have the necessary checks set up for various browsers, when to use what, and if to include the JS snippet above at all. Ah, the modern web.
With just a little bit of understanding, CSS trickery, and experimentation, we were able to create a visually stunning effect.