CSS aspect-ratio

Stop hacking CSS aspect-ratios and start using aspect-ratio.

Course image for CSS aspect-ratio

Responsive squares

Once in a while you might need to create a responsive square or create the perfect fit for a video source. We'd normally create this with some 'hacky' CSS padding at the top or bottom of an element:

/* 1:1 aspect ratio */
.square {
  padding-bottom: 100%;
}

/* 16:9 aspect ratio */
.video {
  padding-bottom: 56.25%;
}

You might be wondering the reasoning behind it, why would you pick padding-bottom over the height property? You can ofcourse set the height of an element to 56.25%, but by doing this the height and width of the element are calculated seperately. True, it is responsive. But not the responsiveness we'd like it to have.

Padding values are based on the container's width. Meaning if the width changes, the padding also changes. It works perfectly fine if you need a responsibe square. But if you add content to the box, you'll notice it loses the square dimensions. That's because the padding is added to the content of the element.

One way to fix this is to create a wrapper inside the box element en position it absolute in the box, like so:

See the Pen Old aspect-ratio hack by Wesley van Drimmelen (@elDrimm) on CodePen.

Whilst this may not be ideal, it works. However it requires some additional HTML and CSS and the position absolute might not do exactly what you want to box to do. What happens when the content overflows the padding?

Aspect ratio meme

Aspect-ratio to the rescue

Calculating the aspect ratio using padding is not ideal, but it's doable. However there's a new kid on the block, the aspect-ratio property. It's more clear, easier to use and does not overhaul the padding scope. The only problem with the new aspect-ratio property is that it is only available in modern browsers (or soon to be added).

See the Pen Aspect-ratio property by Wesley van Drimmelen (@elDrimm) on CodePen.

Fallback

Like mentioned above, the aspect-ratio property is only available in modern (the latest) browsers. You can add the @support at-rule to check whether the aspect-ratio is available, if not perform the padding trick.

@supports not (aspect-ratio: 16 / 9) {
  /* Put the fallback here */
}