Fix layout shifts by preserving aspect-ratio at responsive sizes

Uses `aspect-ratio` property to constrain height and width of render image's container to allow responsive resizing
while maintaining the original aspect ratio and avoiding layout shifts.

Previously, even though `width` and `height` attributes were passed to the `img` element, Chrome (and probably others)
weren't reserving space for the image as expected because CSS `width`/`height` were both `auto`. At least one of them
needed to be a fixed value in order to maintain aspect ratio. Even with this change, it doesn't seem possible to
constrain both width and height on the same element at the same time — only one or the other works.

The change introduced makes the `img` element constrain width using `max-width` while the parent element constrain
height using `max-height` and `aspect-ratio`. This way, we can get responsive sizing on both axes while obeying the
constraints.
This commit is contained in:
Sangeeth Sudheer 2025-03-16 08:37:22 +05:30
parent b4813b0068
commit 28ba526714
No known key found for this signature in database
GPG key ID: F6D06ECE734C57D1
2 changed files with 13 additions and 12 deletions

View file

@ -440,18 +440,19 @@ footer a {
/* images */
figure>div {
width: 100%;
display: flex;
justify-content: center;
}
figure {
.img-container {
aspect-ratio: var(--w) / var(--h);
max-height: var(--figure-img-max-height);
width: auto;
margin-inline: auto;
}
figure img {
max-width: 100%;
max-height: var(--figure-img-max-height);
width: auto;
height: auto;
margin-inline: auto;
img {
display: block;
max-width: 100%;
height: auto;
}
}
.dark .img-light {

View file

@ -46,7 +46,7 @@ and build the img class string as "img-tag1 img-tag2 ..."
{{/* Use the computed classes on the rendered figure */}}
<figure class="{{ $classes }}">
<div>
<div class="img-container" {{ with $imgResource }}style="--w: {{ .Width }}; --h: {{ .Height }};"{{ end }}>
<img loading="lazy" alt="{{ .Text }}" src="{{ $url }}" {{ with $imgResource }}width="{{ .Width }}" height="{{ .Height }}"{{ end }}>
</div>