Responsive embedded videos
Illustration by KU-RO-DO

Responsive embedded videos

, by

Embedded videos hosted by video hosting services (like Youtube or Vimeo) don’t scale properly on fluid Responsive layout. There’s a way to remedy this without JavaScript but only CSS.

Let’s say we have a video which has dimensions of 640 x 360px. When navigate on smaller devices, we want the video to shrink and keep its proportions ; like Responsive images do when setting max-width: 100%.

Many of us have a JavaScript approach :

  1. Get the width and height of the original video
  2. Calculate a ratio (%) = height / width * 100
  3. Set a new height in JavaScript on resize (new height = width x ratio)

Chris Coyier and Paravel built few years ago a great and lightweight plugin which does exactly this : FitVids.js.

The side effect of the JavaScript approach is what Ethan Marcotte describes, in his last book Responsive Design : Patterns & Principles, as a “slight visual stutted” when resizing the browser. Hopefully there is a CSS approach which works perfectly specially if your videos share a same ratio (which is often the case).

Keep videos ratio with CSS

The technique was brought by Thierry Koblentz in 2009 in the article : Creating Intrinsic Ratios for Video. The key is to set the padding-top of the parent block of the video in percentage : “Padding property is the magic that styles a box with an intrinsic ratio”.

Indeed, a percentage padding is, by definition, based on the width of the containing block (W3C source). So to have a block that fit the video’s dimensions, we just need a padding-top set with the video’s ratio :

/*
 * Ratio of our videos : 
 * 360 / 640 = 56.25% 
 */
.video-wrapper { padding-top: 56.25%; } 

Next step is to put the video inside the block : easy thing, we add a relative positioning on .video-wrapper and, inside, an absolute one on the video with a top:0 to lay the video inside the container :

.video-wrapper {
  position: relative;
  padding-top: 56.25%; /* ratio of the video */
}

  .video-wrapper__iframe {
    position: absolute;
    top: 0;
  }

Dimension attributes and !important

When embdeding videos, the iframe’s integration code provided has dimensions attributes. Working Responsive, we might want to remove them, but it is actually better to keep them because “user agents are expected to use these attributes as hints for the rendering” (source) and then load the iframe quicker.

Unlike images we can’t write <iframe width="100%" ...> because since HTML5 the width attribute of an <iframe> can be only in pixels. Also height="auto" would mean 0.

So I suggest keeping the original dimensions on the iframe (good for the browser) and force it in the CSS (good for the responsiveness) using the !important keyword - which was specially created to overload inline style attached directly to the element -.

UPDATE : Harry Roberts recently wrote a nice article about !important which somehow re-establish its usefulness and avoid any “religious debate”.

Final code

<div class="video-wrapper">
  <iframe class="video-wrapper__iframe"
          src="https://player.vimeo.com/video/28236362" 
          width="640" 
          height="360" 
          frameborder="0"
          webkitallowfullscreen 
          mozallowfullscreen 
          allowfullscreen></iframe>
</div>
.video-wrapper {
  position: relative;
  padding-top: 56.25%; /* ratio of the video */
}

  .video-wrapper__iframe {
    position: absolute;
    top: 0;
    width: 100% !important;
    height: 100% !important;
  }