CSS Ratios

The more sites I design responsively, the more I see the need for maintaining an element’s aspect ratio. The idea being that as the browser window widens and shrinks, both the element’s height and width scale proportionately.

However, there is not a clear and simple way to do this. Most solutions I’ve found require a minimum of two elements to make this type of functionality work. Other solutions require Javascript instead of straight CSS. While not nearly as bad, this feels a bit like the old way to achieve rounded corners before border-radius.

What I want is a CSS property that can maintain set proportions for any given element. Currently there is only one element that has this functionality with the least amount of CSS. An img tag with a percentage-based max-width or width property will scale the element’s height proportionate to the displayed width as the window size changes. As far as I’m aware there is no way to make an element behave like an img tag.

Maybe an expansion of the box model is in order so we can say box-sizing: img-box;, which should also inherit the properties of border-box. Another option could be a straight ratio:maintain; declaration could be added to handles this. We may need to throw in our dimensions as well, so maybe there are ratio-height and ratio-width properties added. Of course if CSS ever gains some rudimentary math functions, we might be able to take care of our ratios there.

Blah, blah, blah…how about a use case?

The biggest area I see this need is for embedded content. This is content that often ought to scale like an image, particularly videos. I also see cases where an element does nothing but display a background image, like a logo, and that element needs to scale proportionately to the window size. I’ve used methods to create proportionately scaling buttons as well.

You could just use media queries

Well, yeah…I’m still going to use media queries, but responsive design is about the in between. I might have media queries that even kill the whole proportions thing, but the ability to have it in an area where it makes sense would be nice.

Fine, fine…you said there were options for ratios now

Yes, thank you.

I have two options to show. They’re CSS only—that’s my criteria for this. So, with out further ado…

Two Elements and a :pseudo

This is probably the more common solution as far as I’m aware. The idea is to use an :after pseudo element and a child element to create the ratios. In the below example I’ve separated the padding-top property into individually scoped :after pseudo elements. The ratios I’m using are the more common video types; 4:3, 16:9, and the epic 2.39:1.

See the Pen Aspect Ratio Containers by Philip Zastrow (@zastrow) on CodePen.

The Hidden Image

I’m actually using this method on the Notre Dame Magazine website. Unfortunately this is the modern-day equivalent of the spacer gif. The idea is that the image size with a max-width or width property with a percent-based value would scale the parent element in a proportionate manner.

See the Pen IMG-based Aspect Ratio Containers by Philip Zastrow (@zastrow) on CodePen.

You can also use this method to add some additional CSS styling to an image that can’t be added directly to an img tag.

Final Thoughts

As far as solutions I’m aware of, I think the Two Elements and a :pseudo is the way to go for most cases. However, I can see and have had situations where the Hidden Image method makes the most sense. If you go the image route make sure it is working semantically and not just used for sizing the element. In the case with the Notre Dame Magazine website, the img tag has a title attribute describing the image in the background.

Keep in mind that these ratios don’t need to be something that exist outside of media queries. Let the content dictate the layout and use of ratios.