HTML5 Video, A Responsive Solution

HTML5 Video

We've recently published a single page for a client where the main feature was a full-wide video on the top followed by a registration form for an incoming event a bit further down.

The video was the grand opening and it had to work on a range of devices. Their audience is mainly on mobile and their stakeholders typically still browse the web on IE 11.

A bit of a challenge but I think we did fine with a HTML5 video block and some Javascript in order to better serve the appropriate resolution of the video given the wide range of screens we had to target. I share our solution for further reference, it is as an example easy to customize to specific needs.

First the HTML block.

<video id="video"
  preload="auto" autobuffer playsinline
  muted controls autoplay
  style="min-width:100%; min-height:100%;"
  poster="../video/video-screen-1920x1080px.jpg">
  <p>Your browser does not support the HTML5 Video element.</p>
</video>

A recent update to iOS disallows video with sound on Apple device. So the video has to be loaded muted. We put the audio back on wider screens via JS.

Also there is no source yet since we intend to serve an appropriate resolution and again we use the code below to do so.

<script type="text/javascript">
  (function($) {

    var ie = 0; // Detect IE 11
    try { ie = navigator.userAgent.match( /(MSIE |Trident.*rv[ :])([0-9]+)/ )[ 2 ]; }
    catch(e){}

    var _video = $("#video");
    if ($(window).width() <= 540) {
      console.log("Detected screen less than 540 pixel.");
      _webm = "540p.webm";
      _mp4  = "540p.mp4";
      _ogv  = "540p.ogv";
    } else if ($(window).width() <= 720) {
      console.log("Detected screen less than 720 pixel.");
      _webm = "720p.webm";
      _mp4  = "720p.mp4";
      _ogv  = "720p.ogv";
    } else if (($(window).width() <= 1080) || (ie != 0)) {
      console.log("Detected screen less than 1080 pixel.");
      _webm = "1080p.webm";
      _mp4  = "1080p.mp4";
      _ogv  = "1080p.ogv";
    } else {
      console.log("Detected screen greater than 1080 pixel.");
      _webm = "1440p.webm";
      _mp4  = "1440p.mp4";
      _ogv  = "1440p.ogv";
    }

    if ($(window).width() >= 1200) {
      // iOS requires video to be muted to be auto-played
      _video.removeAttr("muted");
    }

    _src_webm = "<source type='video/webm' src='../video/" + _webm + "'>";
    _src_mp4  = "<source type='video/mp4' src='../video/" + _mp4 + "'>";
    _src_ogv  = "<source type='video/ogv' src='../video/" + _ogv + "'>";

    _video.append(_src_mp4);
    _video.append(_src_webm);
    _video.append(_src_ogv);

    _video.get(0).play();

  }(jQuery));
  var $mcj = jQuery.noConflict(true);
</script>

jQuery is used for convenience but it is not strictly necessary.

Detecting IE 11 is instead necessary since that specific browser won't play video at a resolution bigger than 1088p and we still want to serve a higher resolution to other browsers.

And finally the accompanied CSS, which is really minimal.

.video-placeholder {
  width: 100%;
  height: auto;
  margin: 0 auto;
  padding: 0;
}

video {
  box-sizing: border-box;
  width: 100%;
  height: auto;
}

The box-sizing property was added to the body altogether, I added here to the video tag as reminder. It is not determinant but it helps in many cases where paddings and margins are in the way.

Hope that helps and saves you some time.

ps. The code used to detect IE 11 is taken from a question answered on Stackoverflow.