Making videos responsive

NOTE: Please see updated post/code here: Responsive Videos (updated) (works with latest Video JS version at time of writing – 3.2.0)

As part of a recent project, I needed to find a way to make self-hosted video (i.e. video files uploaded to client’s hosting server rather than YouTube or the like) responsive.  I.e. so they shrink down proportionally with screen size.

I decided to use the VideoJS plugin as a good way to support both HTML5 video (for those browsers that will display it) and a fallback flash version (for those browsers… namely older versions of IE… that won’t).

Making HTML5 video responsive is simple.  Making the flash fallback responsive is not simple.  It took me literally days.  Which is why I decided to post the solution here.

The Responsive Video Solution

NOTE: Please see update towards the bottom of this post; I have modified the original CSS to ensure VideoJS fullscreen functionality continues to function correctly.

Please see example here: http://skybolt.xssl.net/~hexagon2/responsive-video/ – try resizing your screen in an older version of IE, and the video should still resize.  In the example, I’m using WordPress & the WordPress VideoJS plugin, but I believe this should work with a non-WP site and the standard VideoJS script too.

The solution is entirely HTML/CSS based (i.e. no javascript in addition to that used by VideoJS), and is essentially a modified version of the technique described on A List Apart here: http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/.

The normal Video JS code is wrapped in a containing div as follows:

<div class="videoWrapper">  [Video JS code here...]  </div>

The CSS is what does the trick.  It does rely on having a videos of fixed proportion (hence the 41% value), but I wonder whether this could also be combined with a modification of the Fit Vids script (which currently just works with hosted video from YouTube etc) to take this constraint away.  For my purposes, fixed proportion was fine.

    .videoWrapper {
    position: relative;
    padding-bottom: 41%; /* video dimensions - width/height */
    padding-top: 0px;
    height: 0;
    z-index: 1;
    overflow: hidden;
    }

    video {
      position: absolute !important;
      top: 0;
      left: 0;
      width: 100% !important;
      height: 100% !important;
      z-index: 1;
    }    

    .videoWrapper .video-js-box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
    z-index: 1;
    }         

    .videoWrapper object,
    .videoWrapper embed {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100% !important;
      z-index: 1;
    }        

    .video-js-box .vjs-controls {
      z-index: 1;
    }

    .vjs-spinner {
      display: none !important;
    }


And there you have it – a responsive video – not only in browsers that support HTML5 but in those that don’t too.

I hope that helps someone!

Update 17th January 2012

Based on some of the comments received below, I thought it would be worth posting an update, covering two things:

1. A fix for the broken ‘full screen video’ problem

@Robert Roy kindly pointed out that the method outlined above appears to break the fullscreen functionality of VideoJS. I have therefore revised the CSS as follows. Note that you may also need to adjust the z-index property on other elements within your page, to ensure the fullscreen video always sits on top of other content. Different browsers seem to create different problems with this (even more so than usual!), so make sure you test appropriately.

/* Videos */ 

.videoWrapper {
	position: relative;
	padding-bottom: 41%; /* video dimensions - width/height */
	padding-top: 0px;
	height: 0;
	z-index: 1000;
}

video {
  position: absolute !important;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
  z-index: 1;
}    

video.video-js {
  z-index: 1000;
}               

.video-js-box .vjs-controls {
  z-index: 1002;
}

.video-js-box .vjs-big-play-button {
  z-index: 1002;
}

.videoWrapper .video-js-box {
	position: absolute;
	top: 0;
	left: 0;
	width: 100% !important;
	height: 100% !important;
	z-index: 1;
	background: #000000;
}         

.videoWrapper object,
.videoWrapper embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100% !important;
  z-index: 1;
}        

.vjs-spinner {
  display: none !important;
}

.video-js-box img.vjs-poster {
  height: 100% !important;
  width: 100% !important;
}

2. Where the code goes

This is in response to a question posted by @Mark – where does the code above go?

The css can be added to standard styles.css file in your theme (wp-content/themes/your-theme-name/styles.css).

The containing

<div class="videoWrapper">...</div>

needs to be added around the result of the video js shortcode.  There are two ways of doing this: either use the HTML editor within a post, so you’d end up with something like this:



or alternatively (what I did when I originally worked this out for a client project), create a custom field for the video to be uploaded to, then in the relevant php file (this might be in page.php for example), you would have something like this:

echo do_shortcode('');

(where $mp4 and $webm are variables containing the path to the relevant video files, grabbed from the custom fields).

24 thoughts on “Making videos responsive

  1. Can’t seem to get the videos to play on Firefox – but fine on other browsers. I see yours works on Firefox – wonder what I am doing wrong? Any hints?

    1. @Pamela – sorry it’s taken so long to reply… holidays intervened!

      If you’re still having problems getting this to work, send me a link to the site & I’ll try and have a look when I get a moment.

      What video formats are you using?

  2. Hi there, this little trick works quite well on my responsive theme. However, for users who are viewing on a desktop browser, it seems to break the fullscreen functionality of VideoJS.

    1. @Robert – thanks for the tip, good spot. It looks to me like a CSS/Z-index issue – the full-screen container just needs to be brought to the front of the screen, so everything else is hidden. Although in my experience Z-index is never quite as simple as one expects it to be 🙂

      Will work on it when I get a minute…

  3. Hi there,

    I’m having problems with responsive video, your soloution looks fantastic but I can’t work out what css/html/php files need altering and where the code needs to be inserted?

    Any help would be greatly appreciated as I’m pretty new to all this!

    Thanks in advance,
    Mark

    1. @Mark – please see my update above in the main post, hope this helps.

      @Robert Roy – I have updated the CSS to address the fullscreen issue – again, please see update above. It’s not 100% perfect, but it’s a lot better than it was! You may find you have to adjust z-index settings on other elements on the page to ensure the fullscreen video sits on top.

  4. I’m not sure if I’m going bad but I can’t seem to get either of them to work any more. Are you aware if updating WordPress would stop this from working?

    1. @Robert Roy,

      I wouldn’t have thought that a WordPress upgrade would cause a problem, although I notice there is a new version of the WordPress VideoJS plugin (to what I’m running) – to incorporate the new version (3 I believe) of VideoJS itself.

      I haven’t had the time to test this out on the new version yet (will try to some point soon!), but I gave someone a hand the other week who I believe was using the newer version of VideoJS. It was using a different containing div, and so the CSS needed to be altered slightly to pick up the video.

      Here’s what I suggested then:
      “in your CSS file, try changing .video-js-box to .video-js (you may also need to add some more !important statements to the CSS within this selector – so that they are not overwridden by the default VideoJS CSS (e.g. position: absolute !important;).”

      Not sure whether this is what’s causing your problem or not, but it’s at least worth having a look at the CSS in Firebug to see whether something similar is going on!

  5. i did just what you said but nothing seems to work..

    you also said the normal video is wrapped in videoWrapper.. this is something i did not see either.. is this out dated?

    i also tried wrapping that div around the short code.. nothin

    1. @chris

      I believe the new version of VideoJS uses different containing divs, which may well be what is causing your problem. Please see my comment above (03/03/2012 to @RobertRoy) regarding this. Hope that helps. I am hoping to update this post/create a new one based on the new version of VideoJS – but just need to find a spare moment to do that!

      Regarding the containing videoWrapper div – this is something you should add around the normal videoJS code… apologies if my wording is unclear there!

  6. I think this solution doesn’t work for the new version of video.js (3.0 and above)? Might save people time (like me!) if this is made clear in the article!
    Hopefully someone will find an alternative solution for the new video.js soon:)

  7. I am trying this with a fresh copy of VideoJS version 3.2.0 with no luck! I can see that the wrapper is indeed going 100% (I have nothing in the page but the video-wrapper and the video-js code). The video just defaults to the 300×150 or if I explicitly set a width=’xxx’ and height=’xxx’ then it just uses that…

    any ideas?

    THANKS!

    1. @Tyler & @Harry – please see my comment on 3rd March and see whether incorporating the changes I mention there makes any difference – let me know. I am still planning to update this post with clearer instructions for the new version, but client work is coming first at the moment I’m afraid!

    1. @Martin – please see my comment on 3rd March, and also updated post here which includes revised code for new VideoJS version.

      The only difference is updating the CSS to use .video-js rather than .video-js-box – which the new version of VideoJS uses.

Leave a Reply

Your personal information will be processed & stored in line with our Privacy Information Policy. Please do not enter personal information into the comment field.

Your email address will not be published.

Ready to talk? Call +44 (0)1235 811 088 or email for a no-obligation discussion about your new website.