Wow, this is a tricky one! But yes, I’ve found a way to do it in CSS.
As you found, aspect-ratio
doesn’t seem to work to make a vertically-stretched flex child <div>
as wide as it is high. So I tried using a small 1:1 <img>
as the flex child, hoping that the intrinsic aspect-ratio of the image would cause the width to stretch proportionally with the height. That didn’t work — it only stretched vertically. However, switching from flex
to grid
helped in that department. So step 1 gets us a square box on the left which matches the height of the content on the right. Here is a snippet to demonstrate.
.card {
background: lightgray;
display: inline-grid;
grid-template-columns: auto auto;
gap: 1em;
border: 1px solid #aaa;
box-shadow: 0 0 1em rgb(0,0,0,0.3);
margin: 2em;
}
.intrinsic-1x1 {
align-self: stretch;
}
.content {
font-size: 1.5em;
}
<div class="card">
<img class="intrinsic-1x1" src="https://donald.net.au/bugs/1x1-tiny.png">
<div class="content">
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
</div>
<div class="card">
<img class="intrinsic-1x1" src="https://donald.net.au/bugs/1x1-tiny.png">
<div class="content">
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
</div>
Then to finish, we absolutely position a <div>
over that square space — height: 100%;
in combination with aspect-ratio: 1/1;
works in this scenario. Then it’s just a matter of putting our desired <img>
inside and use object-fit: cover;
to scale and crop it to the space.
.container {
background: lightgray;
display: inline-grid;
grid-template-columns: auto auto;
gap: 1em;
border: 1px solid #aaa;
box-shadow: 0 0 1em rgb(0,0,0,0.3);
margin: 2em;
position: relative;
}
.intrinsic-1x1 {
align-self: stretch;
opacity: 0;
}
.content {
font-size: 1.5em;
}
.overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
aspect-ratio: 1/1;
}
.overlay img {
height: 100%;
width: 100%;
object-fit: cover;
}
<div class="container">
<img class="intrinsic-1x1" src="https://donald.net.au/bugs/1x1-tiny.png">
<div class="content">
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class="overlay">
<img src="https://www.celebritycruises.com/blog/content/uploads/2022/01/most-beautiful-mountains-in-the-world-kirkjufell-iceland-1024x580.jpg">
</div>
</div>
<div class="container">
<img class="intrinsic-1x1" src="https://donald.net.au/bugs/1x1-tiny.png">
<div class="content">
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class="overlay">
<img src="https://www.celebritycruises.com/blog/content/uploads/2022/01/most-beautiful-mountains-in-the-world-kirkjufell-iceland-1024x580.jpg">
</div>
</div>