Responsive ratio keeping box

By Kathrin

How to create CSS only responsive divs that keep their ratio?

Discussion Sometimes you would like to include a third party widget like a video into your page. Usually iframes are used for including such things, but iframes are a technique back from the old days and have a fixed width and height — thus not allowing them to react in a responsive way.

Most YouTube videos have a ratio of 16:9. If you change your device width you have to calculate a new height for the box. You can do that with JavaScript, but there is also a flexible CSS-only solution, which we will show you here.

Groundwork

First we need to know some mathematical basics: how you can calculate the percentage ratio height to width of a box. If the percentage height of the box is relative to its width, the box will keep its ratio on all devices.

The mathematical formula to calculate the percentage from ratio a:b is: > (b ÷ a) * 100

For example, given the ratio 16:9, the calculation is > (9 ÷ 16)* 100 = 56.25%

How does calculating this help us? Here comes the magic of CSS. If you have a div or any other box element with a given width and you use percentage value for the padding of this box, the padding will be relative to the width of the box. Therefore, if your box is 500px wide, 56.25% would be 281px ( or 282px — depends on the browser) high.

This still works when you have a percentage width value on your box, because this width will be relative to the surroundings. If, for example, your box has a width of 100%, the padding will be relative to whatever 100% width of the box means.

Tying it together

How does this knowledge fix our initial problem? When you add a large amount of padding-top to a box, the content will be simply pushed down. Therefore, we need to wrap things up a little bit..

Here’s the markup you’ll need for your responsive box:

`<div class="ratio-box ratio-16-9"> <iframe class="ratio-content" width="560" height="315" src="https://www.youtube.com/embed/5lH8X39iF8w" frameborder="0" allowfullscreen> </iframe> </div>`

Now you have a ratio-box wrapper around the ratio-box content

Now let’s add some CSS to it:

`.ratio-box { position: relative; width: 100%; } .ratio-16-9:before { content: " "; display:block; padding-top: 56.25% } .ratio-box .ratio-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }`

`@mixin ratio-box(\$a, \$b) { &:before { content: " "; display:block; padding-top: percentage(\$b / \$a); } }`