Keeping a Fullscreen Background Video “fullscreen” on Vertically Oriented Displays

TL;DR
Use JavaScript to preserve the aspect ratio. And here’s the code:

I ran into a unique layout problem recently while making my own personal wedding website. The problem is this: a fullscreen background video looks and renders fine on most normal “landscape” oriented displays, but once you switch to a “portrait” oriented display, the full screen effect breaks as evident by white space below the video.

Case in point:

Pretty horsey

It should be noted that a common solution here is to hide the video completely on mobile screens and render some static content instead. Responding to the constraints of the viewing medium is what responsiveness is all about. However, I want my mobile visitors to have a similar experience as my desktop and even tablet device users.

Here’s a site I came across that does it well: http://www.shiftbrain.co.jp/:

shiftbrain.co.jp

Alright let’s continue.


A few things to note about my setup:

  • I’m using the 56.25% bottom padding method for full screen video. If you’re using bootstrap’s responsive embed class for this, it’s the same thing underneath. For this solution you will be removing this CSS rule. It’s too rigid as it assumes a fixed aspect ratio. This will make more sense shortly.
  • I’m using the CSS3 vh type for height so that the initially rendered video container takes up the entire viewport height hence the white padding below. Here’s the browser support for vh. All modern desktop and mobile browsers support it. IE8 is typically SOL. We will be using this rule for my solution.

And here’s the basic code for markup and styling so far:

index.html
styles.sass

If you’ve ever seen the magic 56.25 percentage before and wondered what it is, it’s simply the ratio between 9/16 which happens to be the ratio of a lot of embedded videos as well as monitor sizes. You will typically see that ratio written out as 16:9. I’m mentioning this because my solution will work with any ratio so long as you know what ratio your video is. From this point forward, feel free to replace any mention of 16/9 with whichever ratio you’re using.

As mentioned earlier it’s impossible to take a 16:9 ratio “landscape” oriented video and make it fit in a screen where the height is greater than the width a.k.a. mobile. It would be like watching a movie in the theaters with the curtains on both sides semi-closed. That actually turns out to be the intuition behind the first half of the solution reflected here:

Curtains closed

The second half of the solution is for the opposite use case. Ever heard of an ultra wide monitor? Do a quick search and you’ll see the numbers 21:9 come up frequently. Instead of cutting off the sides of the image, we now have the opposite issue which is white space on the left and right sides as reflected here:

Curtains open but now the screen is too wide

How do we address this? Easy. It’s almost the exact opposite of how we deal with a narrower screen:

If you believe that the loss of information is still worth it, then continue. Maybe like me, your video is a montage of closeups, and the general “feeling” is still there. Maybe you just don’t have the time to create a mobile only view. Onto the solution.


The solution in pseudo code is as follows:

  1. Check the ratio of the window width to the window height.
  2. If this ratio is less than 16:9 or more specifically if the height of the viewport divided by the width of the viewport is greater than 0.5625, handle a height centric display.
  3. If the ratio is greater than 16:9 or more specifically if the height of the viewport divided by its width is less than 0.5625, handle a width centric display.
  4. For each of the two conditions calculate the new 16:9 ratio. Then set the styles and center the video element.
  5. Add some sort of listener for screen resizing, and go through steps 1 through 4 again if a resize event occurs.

And here’s the JavaScript:

app.js

Remember to replace the 16:9 ratio calculations with whichever aspect ratio you’re working with.

Here’s the finished product in action:

That’s pretty much it. Thanks for reading!

Link to the JSFiddle.