aspect-ratio and grid

I’m currently investigating the new aspect-ratio declaration and plan to write an article about it. However, I got stuck on aspect ratios in a grid context. Chrome/Safari and Firefox do something different here, and I understand neither approach. So I hope I can get some help.

aspect-ratio is currently supported by Chrome 90, by Firefox 88 with the correct flag enabled, and by Safari Technology Preview. I tested mostly in the first two — for complicated reasons I cannot install STP right now, but a kind Twitter follower sent me a few screenshots. It behaves as Chrome.

I'm writing a CSS book.

First, a general remark. aspect-ratio is intentionally a fairly weak declaration. It gives way if other constraints on boxes make the requested aspect ratio impossible. Take this example:

.my-box {
	width: 100px;
	height: 50px;
	aspect-ratio: 16/9;
}

The box has a fixed width and height, and they overrule the aspect-ratio. The box will thus have a 2/1 aspect ratio, as dictated by its width and height, and not a 16/9 one.

Flexbox

With that in mind, let’s first look at aspect-ratio in a flexbox environment. I think I understand what’s going on here, and the browsers all do the same, so this is a good reference point for the grid problems we’ll encounter later.

Flex items take their width from the flexbox environment. In my example they have a flex-basis: 30%, but they could also have a width or even no width/flex-basis definition at all. In all cases the flexbox algorithm decides on the width of each item.

Once the width has been determined, it’s time for the height. Let’s assume it’s not set. In flexbox, height: auto means not “as high as you need to be for your content” but “as high as the highest box in your row.”

That is, naturally flexbox would give the boxes an equal width (because that’s what my flex declarations say) and an equal height (because that always happens in flexbox). Apparently, this counts as a set height for the aspect-ratio algorithm.

As a result the 16/9 value is ignored because the 4/3 results in a larger height, and this value is therefore the one that determines the height of the entire row.

As you see, the third box in this example does have the correct aspect ratio. That’s because it has an explicit height: min-content: set your height to whatever your content needs, and, more importantly, ignore the row height of the flex box. This, apparently, gives the aspect ratio algorithm the opening it needs to set the height to the one requested by the aspect-ratio: 16/9.

I’m not sure if my reasoning is right. I am very certain that this works in all browsers, though, so you can use height: min-content in production straight away. (max-content also works. There’s no real difference between the two in height declarations.)

flex aspect-ratio and min-content

The problem: grid

Now we get to the problem: grid. To follow along, please look at the example below in Firefox 88 with the aspect-ratio flag on, and in either Chrome or Safari Technology Preview.

I expected grid to more or less behave the same as flexbox: the widths are set by the grid, the heights by the row height, and getting the proper aspect ratio would require height: min-content. That last clause is correct: the min-content trick works as it does in flexbox. It’s the behaviour of th 16/9 box without min-content that surprises me.

Here, again, the third box has height: min-content and takes the correct aspect ratio, which means not obeying the row height, in all browsers.

grid aspect-ratio and min-content

Firefox first. All boxes get their correct aspect ratio and they all have the same width, as the repeat: (3,1fr) grid template dictates. That means their height differs. More importantly, the grid container box now becomes only as high as is necessary to contain the items as they would have been without their aspect ratio.

I am 99% certain that the grid container behaviour is a bug. I am less certain whether the aspect-ratio being obeyed is also a bug.

In Chrome, the second and third box behave as expected: the last box becomes less high than the row height because of height: min-content, and the second box dictates the row height with its 4/3 aspect ratio.

But what’s up with the first box? It appears that it takes the row height as a given, but then sets the width to the value dictated by the 16/9 aspect ratio, ignoring the fact that this box now overflows its proper grid placement. Is this a bug? Or does height count for more than width in a grid context? I don’t know.

In the second example all grid items have min-height: 100px. In all browsers they they calculate their width from their aspect ratio. Thus they break the grid-defined widths. This is understandable, given that the explicit height declaration is “stronger” than the implied widths from the grid definition. (Or rather: I devoutly hope I’m right here and not talking nonsense.)

grid aspect-ratio and min-height: 100px;

Thus maybe Firefox on the one hand and Chrome/Safari on the other are not as far apart as one would think from the first grid example. Still, something is buggy in that example. I just can’t figure out what it is.

Stumped. Please help.

I'm writing a CSS book.

This is the blog of Peter-Paul Koch, web developer, consultant, and trainer. You can also follow him on Twitter or Mastodon.
Atom RSS

If you like this blog, why not donate a little bit of money to help me pay my bills?

Categories: