Let's build an AspectRatio component

We have some HTML and CSS that knows how to presents its contents in a fixed aspect ratio. Let's extract it into a reusable component.

Summary

Let's make an <AspectRatio> component that composes well with images and videos throughout our site.

The component will take a ratio argument, and use that to present its contents in a container with a fixed aspect ratio.

Here's the component:

import Component from '@ember/component';
import { computed } from '@ember/object';
import { htmlSafe } from '@ember/string';

/*
 Example use:

   <AspectRatio @ratio='16:9'>
     // your content
   </AspectRatio>
*/
export default Component.extend({

  tagName: '',

  ratio: null,

  style: computed('ratio', function() {
    let paddingBottom = this.get('ratio')
      .split(':')
      .map(str => +str)
      .reduce((prev, curr) => curr / prev);

   return htmlSafe(`padding-bottom: ${paddingBottom * 100}%`);
  })

});
<div class='relative' style={{style}}>
  <div class='absolute w-full h-full pin'>
    {{yield}}
  </div>
</div>

Now we can use this with our existing components, and we don't have to add one-off options like ar= to our image components!

  {{#p.full-width style='xs xs-pin-top'}}
     {{#ui-link-to-clip clip data-test-id='clip-link'}}
       <div class="border-b border-solid border-black-10">
-        {{ui-img
-          src=clip.posterS3Key
-          ar='16x9'
-          options=(hash w=500)}}
+        <AspectRatio @ratio='16:9'>
+          {{ui-img
+            src=clip.posterS3Key
+            options=(hash w=500)}}
+        </AspectRatio>
       </div>
     {{/ui-link-to-clip}}
   {{/p.full-width}}

👋 Hey there, Ember dev!

We hope you enjoyed this free video 🙂

If you like it and want to keep learning with us, we've written a free 6-lesson email course about the fundamental patterns of modern component design in Ember.

To get the first lesson now, enter your best email address below:

You can also check out more details about the course by clicking here.

Questions?

Send us a tweet:

Or ask us in Inside EmberMap, our private Slack workspace for subscribers.