CSS aspect-ratio for the win
Tags: css, tutorial, frontend
Published: 2021-02-18 10:12:56


Update 😎: If you like to see this tutorial in video format, here is the link!. 

{% youtube -Wv-YuHc0vw %}

So a few days ago a colleague of mine published in the slack from my company that a new CSS property was defined in the  [CSS Box Sizing Module Level 4 specification](https://www.w3.org/TR/css-sizing-4/#aspect-ratio). Is still a Working Draft, so some things could change but are supported already by Chrome and Firefox under an experimental flag.

Yeah, I'm talking about my dream come true, `aspect-ratio` is in progress and is gaining a lot of momentum.

To understand why is this such a big deal, let's cover first what aspect-ratio means in terms of design and what CSS hacks were used until now. 

# Aspect ratio

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhxjyihbvx6eqqv9yjoy.png" alt="Diferent sizes, same aspect ratio">
  <figcaption>Two images with different sizes can share the same aspect ratio, in this case 3:4 - Image <span>Photo by <a href="https://unsplash.com/@chrisleeiam?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Chris Lee</a> on <a href="https://unsplash.com/s/photos/green?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></figcaption>
</figure>

Is a common term used in photography and video where the dimensions of any media resource are expressed as two integers and a colon, it can be `width:height` or `x:y`.

You can find these values everywhere: 
* The most common values for photography are **4:3** and **3:2**. 
* Instagram Square pics use a **1:1**, portraits are **4:5** and landscapes **1.91:1**
* OG Images for social media are **1.91:1**
* Youtube videos and thumbnails enjoy a widescreen of  **16:9**
* If you are reading this from a 15'' **MacBook Pro** your retina display is about **16:10**

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxmxvrkkkrqpfyg0sfze.png" alt="Same picture different aspect ratios">
  <figcaption>Same image with different aspect ratios, 2:3 on the left and 1:1 on the right- Image <span>Photo by <a href="https://unsplash.com/@timschmidbauer?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Tim Schmidbauer</a> on <a href="https://unsplash.com/t/animals?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>
 </figcaption>
</figure>

Well, why this should concern you as a Frontend dev? Should, a lot actually.

Several times you will find the situation where a media resource needs to be represented through UI Elements, a perfect example would be a card with a Youtube video, or a grid showing your latest articles on your webpage. 

If we lived in a world where all devices had the same screen (what a crappy world), then we could easily set width and height to a fixed value. But we leave in a responsive world, maintaining aspect ratio has been increasingly important for web developers, especially as image dimensions differ from element sizes depending on the available space.

Creating intrinsic placeholder containers for images, videos, and embeds and preventing [cumulative layout shift](https://web.dev/cls/) in fluid environments is a must.

So.... how it's was done before?

# The old-good-hack: using padding-top

This hack is written in every experienced frontend dev's handbook, even when is a little bit unintuitive, it actually works and is a well-accepted cross-browser friendly solution.

`padding-top` is based on the parent element's `width`, so if you had an element that is **640px**  and you set a `padding-top: 100%` wouldn't that be equal to **640px**?

A perfect square of 1:1 aspect ratio. 🤯 

Want a youtube video aspect ratio `16:9`? Just use [The Rule of three](https://www.bookofthrees.com/the-rule-of-three-in-mathematics/#:~:text=The%20Rule%20of%20Three%20is,can%20calculate%20the%20unknown%20number.):

`9 * 100 / 16` and your `padding-top` should be `56.25%`

![Mind blown](https://media.giphy.com/media/xT0xeJpnrWC4XWblEk/giphy.gif)

Here is an example of using this hack (in comparison to not using it)

{% codepen https://codepen.io/alvarosaburido/pen/MWbmYqw %}

# CSS aspect-ratio for the win

It's time for magic.

```css
.my-thumbnail {
  aspect-ratio: 16 / 9;
}
```

Just drop `aspect-ratio` on your selector alone and it will calculate a height based on the `auto` width.

BAM!! No more hacks needed.

{% codepen https://codepen.io/alvarosaburido/pen/NWbjqyx %}


I create more examples in this Pen:

{% codepen https://codepen.io/alvarosaburido/pen/poNPmjJ %}

# Can I use?

![Almost](https://media.giphy.com/media/szlSwLwiXBEeQ/source.gif)

Of course, the hype is real until you enter this page and you check that you cannot use it yet in most browsers, only supported in Chromium, Safari Technology Preview, and Firefox Nightly for now.

![Screenshot 2021-02-17 at 22.10.50](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5wg4av8b6861ctz36dfu.png)
 
I hope you learned a lot as I did, let me know your thoughts in the comments.

Happy coding!