Making Video.js Fluid for RWD

Video.js is a pretty, smooth, CSS-styleable video polyfill and my Google-Fu didn't return any responsive examples, so I grokked this out.

May 03, 2012

Now, Uncle Dave is no stranger to video in responsive web design and I currently have a situation where I need to use Video.js on a project. Out of the box, Video.js isn’t super flexible. My first attempts at responsivizing1 it went awry, but I eventually grokked out a 3 step solution.

View the demo

Step 1: Put stuff in the Head

Per the requirements of Video.js, this stuff must be in the head so that it will continue to function on older IEs. You can self-host the files or use their CDN.

<link href="http://vjs.zencdn.net/c/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/c/video.js"></script>

Step 2: Remove height and width

You only need to make a minor edit to the video tag2 from the Video.js example, simply delete the height and width attributes attribute.

<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" poster="http://video-js.zencoder.com/oceans-clip.png" data-setup="{}">
  <source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
  <track kind="captions" src="captions.vtt" srclang="en" label="English" />
</video>

Notice the explicit ID, you’re gonna need that later. You’ll have to modify the following if you have multiple videos on one page.

Step 3: A little window.resize() magic

Just before your </body> tag add:

<script type="text/javascript">
  // Once the video is ready
  _V_("example_video_1").ready(function(){

    var myPlayer = this;    // Store the video object
    var aspectRatio = 9/16; // Make up an aspect ratio

    function resizeVideoJS(){
      // Get the parent element's actual width
      var width = document.getElementById(myPlayer.id).parentElement.offsetWidth;
      // Set width to fill parent element, Set height
      myPlayer.width(width).height( width * aspectRatio );
    }

    resizeVideoJS(); // Initialize the function
    window.onresize = resizeVideoJS; // Call the function on resize
  });
</script>

View the Demo

“Why not use the Video.js API’s built-in myPlayer.width()?” Unfortunately, it turns out that myPlayer.width() will return 100 (pixels) becuase the width is set to 100%. So we rely on the video’s rendered width.

If window.resize() isn’t your thing or you have performance concerns, I found an intrinsic ratio version of Video.js, which is the same principle as FitVids, after the JavaScript fires it’s CSS all the way down. I tend to steer clear of core-hack forks and it had a jQuery dependency, so it’s not for me on this project, but it’s an awesome solution.

  1. Is this a word yet? 

  2. Intentionally didn’t include a WebM source. #hotdrama