Fun with HTML5: video previews


TL;DR The <video> tag is an HTML5 element that is a lot more forgiving and flexible than the common <iframe>.  You can do some interesting things with its attributes, including a looping preview of the video to incentivize people to click – which I get into down below.  At the end of the day though, I would still recommend having your videos hosted by a third-party such as YouTube, Vimeo, or Wistia.  You’ll be giving users more control over their bandwidth and you’ll be able to get better numbers on viewing habits of your audience.

No 3rd Parties Allowed

On a recent project, a client had sent me a number of videos they had professionally done that they wanted on the new website before launch. When I asked for their YouTube, Vimeo or other third-party video-hosting accounts… they didn’t have them.  Not only did they not have them, they didn’t want them either.  In order to get the videos on the site, I had to bring out what seemed to be a forgotten player: the HTML <video> tag.  That project is now done, but it got me inspired to do more with the <video> element and try out a quick exercise: Mouse-over Movie Trailers.  Check out this video I made for my friends’ wedding:

If you want to go straight to see what’s going on under the hood source code-wise, you can check out my Pen HTML5 Video Trailers.  Otherwise, let’s take it step by step.

An HTML5 upgrade

Prior to this client project, I think I worked with the <video> tag directly once in my life.  After doing some digging, I found that the <video> tag has gotten some very cool upgrade since the release of HTML5.  Looking at the W3Schools article on the <video> tag, you will see you can get some options like autoplay, looping, hiding controls – a lot of the same options available to YouTube embeds.  It’s actually a little crazy when you see how many different media attributes you can track with the video tag: Click for craziness.

Moving on. W3Schools shows the following mark up for your video tag.

<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">
  Your browser does not support the video tag.

If you read my blog post on responsive images using Picturefill.js, then the <source> tag will be familiar.  (Quick note: Unfortunately, we can’t append a ‘media’ attribute like we did with picturefill.js in case you were wondering).  So what’s going on with the line “Your browser does not support the video tag”?  Well, that’s supposed to be a fallback for any browsers that don’t support the video tag.

First obstacle: IE 8

The <video> tag is not supported in IE 8 (of course >:\ ) and IE 8 compatibility was important for the client project that started all this.  In the “fallback” proposed by W3Schools is a message to the user. Come on, W3Schools! We can do better than that.

While the HTML5 <video> tag isn’t supported by IE 8, the <iframe> is.  Instead of a message to IE 8 visitors, we are going to write an <iframe> nested inside some conditional comments.  If you’re not familiar with conditional comments, CSS-Tricks has a list of IE conditional comments that’s a handy resource to have bookmarked.  So with our real fallback for visitors using IE 8 or lower our code looks like this:

<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">
  <!-- [lte IE 8]>
    <iframe frameborder="0" src="movie.mp4" width="480" height="300"></iframe>

Something super important to remember is the IE conditional comments are written differently than typical html comments.  This took me an embarrassing amount of time to realize so I’m going to say it again.


IE conditional comments are written differently than HTML comments. Never forget.

Nathan’s last words, 2014


Every movie needs a good poster (attribute)

You’re going to want two posters.  One for a static display and one to play on a loop on mouse over.  The looping .gif you see on mouseover doesn’t come from the actual video itself, but an external file specified in the <video> tag’s attributes.  When making your poster choose a picture you feel will entice people to click on, or at least mouse over, the video.  Because you’re making these posters separately, you could put any call to action you want in the poster file – the world’s your oyster!

I use Photoshop to make my looping gifs.  By importing your video into Photoshop with “import video as layers” you are going to be able to pick which frames you want to include in your looping .gif.  How to make this .gif is outside the scope of this tutorial – but maybe I’ll upload a “how to gif” post to my blog in the future.

Attribute considerations to avoid The Weirdness

A couple things I discovered about working with the poster attribute:

  1. Set your ‘preload’ attribute to “none” or “metadata”.
  2. Set a max-width on your video if your poster image is going to be bigger than your actual video.

If you set the preload attribute to anything other than “none” or “metadata”, your poster might decide how big your video gets played.  That’s weird.

The preload attribute decides what information and how much of it to load before a video is even played. Different devices and browsers handle it slightly differently.  For more information on the preload attribute, thanks to Steve Sounders.

But you’ll be setting your [preload] to “none” or “metadata” anyways because people don’t need to download your entire video as soon as they get to your site.  Unless you video is exceptionally small, you shouldn’t be littering people’s browsers with auto buffering, data hungry videos – let users choose what they buffer and don’t litter!

Don't Litter; it's not cool.

If your poster is larger than your video, you’ll want to set a max-width on your video elements. Otherwise, you are going to get any annoying flickering effect when you mouse over your <video> tag.  The target size will keep changing and it will just feel all round broken – check out the last two examples in my Pen for an example of this weirdness.

Different browsers == Different sources

Your .mp4 video is going to play fine in Chrome – but bring that over to Firefox or Safari and it will be no dice.  You’ll need three different file type versions for each video you upload to the <video> tag.  Here’s a breakdown from Mozilla Developer Network (MDN)

  • MP4 – “natively supported by desktop/mobile Internet Explorer, Safari and Chrome, but Chromium and Opera do not support the format. Firefox/Firefox for Android/Firefox OS supports the format in some cases, but only when a third-party decoder is available, and the device hardware can handle the profile used to encode the MP4.”
  • WEB – “natively supported in desktop and mobile Gecko (Firefox), Chrome and Opera, and support for the format can be added to Internet Explorer and Safari (but not on iOS) by installing an add-on.”
  • OGG (perhaps optional) – “supported in desktop/mobile Gecko (Firefox), Chrome, and Opera, and support for the format can be added to Safari (but not on iOS) by installing an add-on. The format is not supported in Internet Explorer in any way.”

Conversion tool: Miro Video Converter

I use Adobe Premiere Pro and After Effects for video editing, but neither of those programs can export a .webm file.  To show you how uncommon this file type is: The professional video studio that the client had hired had never even heard of the .webm file type – and they do this for a living!

I noticed the Sketch/Swift specialist, Meng To, is using <video> tags on his site Design + Code.  I reached out to him and he told me about Miro Video Converter – a free software that will convert your .webm and .ogg file types for you. Everyone say “thank you” to Meng!

Getting under the hood

Ok! Let’s look at some code.  If you want to see the demo, I recommend going to the actual Pen on CodePen.  Mouse-over detection on the embedded frame can be a little shaky.

This is still pretty buggy on a mobile device.  Fixin’ on a work.

See the Pen HTML5 Video trailers by Nathan Ferguson (@NathanPJF) on CodePen.0

The actual code isn’t that complicated.  First, you will need to include references to your static poster and your teaser/looping gif in the <video> tag mark up.  Reason you need both is because you’ll be constantly overwriting the poster attribute on each mouse-over and mouse-out.  Also, I decided to turn the controls off to hide the black band – the controls will be turned back on only on mouse over and while playing.

<video preload="none" nocontrols data-teaser="/path-to/looping-image.gif", data-preview="/path-to/static-image.png", poster=/path-to/static-image.png">

While your video is playing, you don’t want your mouse-over and mouse-out actions to be reseting the video.  Therefore, my .js contains a check whether the video is currently play before doing any image swaps on the poster.  It should be noted: this script is using jQuery, so load that up before you start!

 $( "video" ).mouseover(function() {
   $teaser= $(this).attr( 'data-teaser' );
   $(this).attr( 'controls',true ); /*turn controls back on*/
   if ( this.paused ) { /*works if video is paused OR stopped*/
     $(this).attr( 'poster', $teaser );

And that’s it!  The rest of the .js is in the Pen, but if you understand the instructions thus far you’ll have your super cool looping HTML5 video previews in no time.

<video> from here on out!  (Probably not)

Having a mouse over preview of the video, in my opinion, is really powerful.  The looping teaser is fun and interactive, it can incentivize people to click on your video and it can speed up decision-making for visitors to decide whether this is the content they are looking for.  YouTube ain’t got that – at least not as of the time I’m writing this.

However, there are some drawbacks to this technique.  For one, it’s pretty labour intensive.  Making your separate poster files, creating the looping gif, converting all the video to different containers… its a lot more work than copy-pasting an iframe embed code.

The biggest issue I have with this technique isn’t the setup involved – I really like Photoshop – it’s the fact the technique isn’t responsive.  The <video> element can be made fluid with CSS, but the video content still isn’t going to adapt.  I’m a huge proponent for responsive content, and unlike the Picturefill technique, there is only one quality size of video available to visitors.  If someone is on a desktop, I want to serve up my high-resolution 1080p version.  If someone is on mobile… what version should they be seeing?  That’s a big advantage of using a third-party service:  viewers can choose what quality setting they want to see, and that speeds up viewing time, saves bandwidth, and saves everybody some money.

Also, without the use of additional scripts or plugins, you are going to get little information on visitor’s viewing habits with the vanilla <video> element.  Using a third-party service like YouTube, Vimeo, or the new-comer Wistia is going to give you rich information you can play with.  And we all know how fun it can be to play with data.


Leave a Comment.