Let's set up the problem: You want a set of cards to display images in a square most of the time, like this:
But since content height might vary, you need to build defensively with CMS authors in mind, so the design should allow for longer content:
Typically, we'd achieve this with a padding hack, or using pseudo-elements to fake a min-height that matches the width of the image. But now, it's safe to use container query units in production (See browser support).
First, define a container on the parent element of the image:
figure {
container-type: size;
}
To use container units, you don't even have to use a container query. You just have to target an element that lives within the container, and then you can use the size of the container – both width and height – as a unit. So to make any aspect ratio a min-height, calculate the percentage of the height needed and apply it to the min-height
value using the cqw
("container query width") unit. One cq unit is 1% of the entire value, so 100cqw
would create a minimum value of "square" like this:
img {
min-height: 100cqw;
height: 100%;
object-fit: cover;
}
Note that this assumes that figure
is a grid cell, which is the quickest way to achieve two side-by-side items that fill the same amount of space.