Creating an aspect ratio CSS utility

Categories


Until we get a native aspect ratio unit in the browser: achieving a controlled height based on a container’s width might seem difficult in a responsive design at first glance. It is actually pretty darn trivial, thanks to good ol’ padding and a touch of positioning magic (read: hacking).

The utility’s code permalink

We’ve got a two for the price of one going on here:

Code language
CSS
[class*='ratio-'] {
  display: block;
  position: relative;
}

[class*='ratio-'] > * {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

.aspect-ratio-wide {
  padding-top: 56.25%;
}

.aspect-ratio-square {
  padding-top: 100%;
}

🔥 Pro tip: The [class*=''] selector looks for elements that contain whatever you put in the quotes. It’s handy for querying parts of a selector when you’re not 100% sure of an element’s construction.

We’ve got two separate classes that specify a ratio and then a shared bit of CSS that is common to both.

The .aspect-ratio-* class creates a relatively positioned container because its direct descendant is absolutely positioned. Adding a top padding value of X% means that the container will have X% of its own width as vertical padding.

This padding value is the magic of the aspect ratio utility, because no matter how wide or narrow the container gets, the height will always be relative to its width. It’s a tidy little CSS algorithm.

The absolute positioning serves two purposes, too: it makes it easier for the child element to fill its container—but more crucially—it prevents that child element from affecting its parent’s padding.

Examples permalink

This utility is flexible and can be used in a number of contexts. Here’s two common ones.

Image gallery

Sometimes it’s handy to render out a list of square images in a grid. We all know images can vary in size, so the mixture of .aspect-ratio-square and some object-fit gives you exactly what you want, with a tiny amount of CSS (even to generate a completely responsive grid).

This is thanks the the .aspect-ratio-square utility having a padding-bottom value of 100%, which is what makes it a perfect square.

Video embed

One thing that can be a bit of a head scratcher is responsive video embeds. Not with the ratio utility, though!

If you add .aspect-ratio-wide to the container of the <iframe>, it adds a bottom padding value of 56.25%, which gives you a 16:9 aspect ratio, regardless of width. The CSS also takes precedence over the width and height attributes, which you can still use to set sensible defaults for if your CSS fails. Progressive enhancement in action.

Wrapping up permalink

With only a few lines of CSS, we’ve got a handy little CSS algorithm that gives us aspect ratio. It’s frustrating that we’re having to use absolute positioning within the utility, but that won’t be the case forever because that magic aspect-ratio unit is only around the corner.

When it arrives, we’ll be able to extend this utility to use the new aspect-ratio unit as a progressive enhancement. Until then, you can read the draft spec in preparation.


Comments

If you liked this post, you might like these ones, too

  1. Make a button element look like a link

    🔥 A handy quick tip.

    Continue
  2. Two simple methods to vertically and horizontally center content with CSS

    Continue
  3. A safer way to vertically fill the viewport

    🔥 A handy quick tip.

    Continue

Become a supporter by joining the Piccalilli Membership

For $5 per month, you get access to a private, friendly Discord community, a regular newsletter, huge discounts on courses and free access to all premium tutorials.

Most importantly, by becoming a supporter, you help make as much content, free-to-everyone as possible on this site, which benefits everyone. As a member, you also get an ad-free experience around the site.

Support Piccalilli by becoming a member

Sign up for updates

Stay up to date with updates from Piccalilli. You’ll get alerted as soon as any new content gets published. You’ll also get updates on upcoming courses and membership features! You can unsubscribe at any time, too.