css3

Responsive Aspect Ratios With Pure CSS

One of the hurdles I faced when beginning to work with responsive designs was the lack of an obvious way to assign an aspect ratio to a container in CSS. This kind of thing can be handled with an image placeholder or Javascript, but neither is an elegant solution. Fortunately, with a little bit of digging, an answer soon presented itself!

The Box Model

CSS gives us an easy way to give an element a “responsive” width declaration relative to the browser window size or other containing parent element by simply using a percentage. What we don’t have is a way to simply declare a responsive height relative to width, maintaining an aspect ratio. The solution I found was a lot simpler than expected and came from examining the W3C’s box model recommendations.

Padding to the Rescue

The answer lies in the box model’s padding specs, of all places. We find that when declaring percentages instead of fixed values for padding, the percentage is calculated based on the WIDTH of the element in question, even if we are declaring a vertical value such as padding-top or padding-bottom. To take advantage of this for the purpose of maintaing our height relative to width, all we have to do is a little math!

Let’s look at the CSS:

figure {
	width: 36%;
	margin: 8px auto;
}

div.stretchy-wrapper {
	width: 100%;
	padding-bottom: 56.25%; /* 16:9 */
	position: relative;
	background: black;
}

div.stretchy-wrapper > div {
	position: absolute;
	top: 0; bottom: 0; left: 0; right: 0;
	color: white;
	font-size: 24px;
	text-align: center;
}

And the HTML:

<figure>
	<div class="stretchy-wrapper">
		<div>Relative Aspect Ratio! Try resizing the browser.</div>
	</div>
</figure>

As you can see in the CSS, all we have to do is nest an element with 100% width inside a “responsive” percentage-based-width parent element, and then declare a % for bottom or top padding based on the ratio we want to maintain. To calculate the percentage needed for any aspect ratio we can use the following formula:

B / (A / 100) = C%

So for 16:9 (where 16 is A and 9 is B):

9 / .16 = 56.25 (%)

And that’s all there is to it!

Some Other Common Ratios

For the not so mathematically inclined, here are some of the percentages for common aspect ratios:

75% = 4:3
66.66% = 3:2
62.5% = 8:5

Have fun and happy coding!

 

19 thoughts on “Responsive Aspect Ratios With Pure CSS

  1. I’m using this to style an image (background: url();) but in Safari and on ios, it won’t display. any thoughts?

    Reply

    1. The technique needs to be implemented as shown in the example using a nested element, not applied directly to the image. Start by copying the example above and then work from there!

      Reply

  2. Hi,
    Thanks for this great tip. Just a word though, if you forget to delete “box-sizing: border-box”, adding borders will deform the aspect ratio.

    Reply

    1. I’m not able to break the example with or without a box-sizing rule, maybe I misunderstood. Can you be more specific?

      Reply

  3. The problem is that if the parent’s aspect ratio is wider then the aspect ratio of the element we want to preserve the aspect ratio of, it will overflow vertically.
    So it is not contained inside the parent element, the same way background-size:contain; would do for a background image for example

    Reply

    1. In our example the parent element exists solely to facilitate the aspect ratio of it’s child element, so the parent needs to have the % width that is desired for the child… no more, no less!

      Reply

  4. Thank you so much for taking the time to share this. So much better than the js hacks I’ve been using!
    😀

    Reply

  5. […] Responsive Aspect Ratios With Pure … – As you can see in the CSS, all we have to do is nest an element with 100% width inside a “responsive” percentage-based-width parent element, and then … […]

    Reply

  6. If I understand correctly, this only works if you change the element’s width. But if you also want to limit the height, it might not work (instead become higher than allowed).

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *