garden /

double-constraint-explicit-images.md

last modified 2025-08-10

if you're a huge nerd about making websites you might care about "cumulative layout shift". in short, if the browser can't predict how much space e.g. an image will take up before it loads, it can predict incorrectly and allocate too little space. then, when the image loads, the space has to be allocated and the entire rest of the page might jump down as you're reading (or worse, clicking!)

the idiomatic way is to add width and height properties to all your <img> and <video> tags that matches their corresponding image files. unfortunately this comes with some extremely annoying downsizes -- namely that trying to pair this with a max-width and max-height might result in stretching or squishing, since the image tries first to attain its specified width and height, then squishes itself down to fit the max-width and max-height constraints, completely ignoring its own aspect-ratio.

the fix here is to pick an axis to constrain, and the other axis is set to auto. e.g. you want max-width: 100%? then set height: auto, and the image's height will adjust to restore the correct aspect ratio.

so what's the problem? well, that's just it: you get to pick one axis to constrain. you cannot constrain along both axes. trying to set max-height while height: auto is happening results in max-height squishing your image and fucking up your aspect ratio again.

there is a fix on top of this: object-fit: contain. this ensures that the displayed image doesn't stretch if the space reserved for the image doesn't match the image aspect ratio. upsides: no stretching! downsides: sometimes you might have empty letterboxing or pillarboxing that looks like needlessly large margins when you don't want it. so this is more of a last resort type thing than an actual fix.

also it looks like chrome just straight up does not respect width or height on either <video> or <source> so chrome users are just gonna have to deal with the jump the page makes when the video loads in


update: nevermind?? it just randomly stopped doing this?? i don't know what i changed but now i can apply both max-width and max-height and it works fine and doesn't squash my images??? i don't know what changed since i did it all outside of any git commits so now we'll never know. -_-