How to implement only css responsive elements with a certain aspect ratio
Tags: css, html, webdev, tutorial
Published: 2020-01-15 20:57:41

If you just want the solution skip to the bottom of the article.

### Why this tutorial
Some time ago I was developing a webapp when the design team manager comes by and tell me that there was a piece of the application that needed to maintain a 16:9 aspect ratio and be responsive, no matter the content inside.
Immediately I said "ok mate, not a problem", but after a while I was like "wait, how do I do that?".
I asked some colleagues and surprisingly I've found that noone already knew how to do it without using Javascript (I always try to avoid using js if possible, especially if I have to add some listener to scroll or resize).

As any developer would do I started searching on Google and yes I've found some answers but I've also found a lot of people asking for it and a lot of questions were not actually working or were not ideal.

That's why I'm writing this tutorial now, I hope it will be the simplest tutorial to understand how to do it.

### Code it
We are going to need **just 2 div**, no matter the aspect ratio we want.
Time is up, let's code it, I'll explain later what's going on:

``` html
<div class="square">
  <div class="content">
    This is a square content
  </div>
</div>
```
``` css
.square {
  border: 2px dotted red;
  width: 250px;
  position: relative;
}
.square:after {
  content: "";
  display: block;
  padding-top: 100%;
}
.content {
  position: absolute;
  width: 100%;
  height: 100%;
}
```

We create a div *square* and inside we create another div with class *content* (class names obviously are arbitrary, those are just semantic to better explain what's the elements purpose).
In the css we add a *border* on the square just to see it easily and we set a width (the width value can be any value, if you want it to be responsive it will probably going to be *100%*) and set the *position* to relative.
We also add an after pseudoelement to the square and add *content* property to make it visible, *display* to block to behave like a block and a *padding-top* of 100%. This padding-top is **THE trick**. By adding this property we are saying: "my element (square) is 250px width and has a padding-top (that count for div dimensions) of 100%, so 250px. The resulting square element will be 250 x 250 px.
This is also where the previous position relative enter the game: if we don't set it to relative and the content element position to absolute the result will be that any content will make the square element to grow in height, thus losing the aspect ratio.
Now to create a 16:9 element or any other aspect ratio just change the padding top this way:
``` css
.square:after {
  content: "";
  display: block;
  padding-top: calc(100% / (16/9));
}
```

this way it will be a 16:9 element (*square* class would be inappropriate then :D).

### Playground/demo
I've created a simple Codepen with some easy examples where you can play and try it out by your own including a responsive one with 100% width. [check it out](https://codepen.io/albertodeago/pen/WNbgeqM?editors=1100).

### Vue component
If you are a Vue enthusiast developer like me I've also created a component to handle this easily, check it out here [vue-aspect-ratio](https://github.com/albertodeago/vue-aspect-ratio)

## Conclusion
For my research this is the best way to address this issue, let me know if you have any questions or tips by commenting or feel free to reach me [on my twitter](https://twitter.com/albertodeago88).