The most meaningful part of the webpage, the content, can be a largely unknown thing. Authors create content in one place and expect it to render well in another. Embedded content adds another level of complexity to this process.

Embedded content, like videos, images, podcasts and tweets often do not translate well to a fluid webpage - so we need to reframe them. This is what Reframe.js does. It wraps embedded content in an intrinsic ratio of the original embed with fluid sizing so that the embedded content looks great within the content.

See the Pen Intrinsic Ratio Animation by Jeff Wainwright (@yowainwright) on CodePen.

Why Reframe.js?

Previous to Reframe.js, FitVids was a standard plugin for making embedded content responsive. FitVids is a great plugin for solving reframing videos. It's written by Chris Coyier and Dave Ruppert. Fitvids takes a chance that most of your content will be 1 of 5 selectors. If those assumptions are correct (and if you're using jQuery) - FitVids is golden. If not, there might need to be little extra code on top of the little extra code added that assumes your embedded content will be 1 of 5 selectors. The reason that Reframe.js was originally made was because jQuery was not being used on a new product at DSC. Reframe.js also: 1. doesn't assume your reframing just videos (by name at least), 2. offers a css mixin rather than inlining css which can make your dom (html) cleaner 3. and offers jQuery plugin that is written in such a way that if unused - it can be shaken out with Tree shaking.

Options

The one option supported by Reframe.js is the ability to add your own css class instead of the default css class js-reframe. This is so that the end result of using the library on a webpage is minimal - just 1 inline style added (for the intersic ratio).

Reframe.js's simplicity in both language and options is meant to make the plugin easy to understand and easy to write code to support your product's end goal.

Plugin Breakdown

CSS (aspect ratio)

In this sass mixin, the default aspect ratio is 16:9 but we can override that to make the reframe a perfect ratio of the embed's original size.

@mixin reframe($el: iframe, $paddingTop: 56.25%){
  padding-top: $paddingTop;
  position: relative;
  width: 100%;
  #{$el} {
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
  }
}

JavaScript

Wrap a selected element in a div.

const frame = element // frame is the elmeent to be wrapped
const div = document.createElement('div');
frame.parentNode.insertBefore(div, frame);
frame.parentNode.removeChild(frame);
div.appendChild(frame);

Add padding to create an intrinsic ratio.

// where the frame is the element and the div is the added wrapper element
const height = frame.offsetHeight;
const width = frame.offsetWidth;
const padding = height / width * 100;
div.style.paddingTop = padding + '%';

Make a plugin for jQuery or zepto.

if (window.$) {
  window.$.fn.extend({
    reframe: function reframeFunc(cName) {
      return reframe(this, cName);
    }
  });
}

Add a check to the top of the plugin which allows us to select the element to reframe with jquery or plain js (Kodos to Jacob Kelley especially here)

let frames = typeof target === 'string' ? document.querySelectorAll(target) : target;
if (!('length' in frames)) {
  frames = [frames];
}

Here's the code you write.

reframe('selector');

See the Pen Reframe.js jQuery Demo by Jeff Wainwright (@yowainwright) on CodePen.

To Dos

Currently, removing the default padding of the ratio (56.25%) that's in the css is being considered because it is overwritten everytime the plugin is called. We've also thought about adding documentation to the repository..

Summary

One of the fun challenges when writing code for content is to support creativity in a controlled way. Reframe.js is a great solve for making embedded content look great on your website. Initially, we didn't know if we would be using jQuery for our product at DSC so FitVids was out of the question - which led me down the path of writing some new code. The end result was Reframe.js. Hope it works well for you if you use it.

We're planning to solve common content problems in the future. If you have questions or ideas in regards to Reframe.js please contact me - links below.

Updates (10-29-16)

Shortly after releasing reframe it gained a lot of unexpected yet appreciated feedback. We've since decided to remove the css dependency and noframe was written. Noframe doesn't wrap the embedded content which allows it to support events more easily. You can read these updates here.