The Weaver's First Pulled Warp Thread: On the Tangled Cost of a Missing `size` Attribute

It happened in a lull, during one of those long, quiet afternoons spent tinkering on a personal project. The page was simple—a collection of photographs from a recent trip. I had been careful, or so I thought. I’d implemented lazy loading, set proper aspect ratios, and even used a responsive image setup with srcset. The page felt fast. But then, I scrolled.

I remember the distinct, jarring sensation, as clear now as the click of a mouse. It wasn't a lag, not in the traditional, waiting-for-something-to-appear sense. It was a betrayal of a promise my layout had made. I’d scrolled to a particular image, a wide landscape shot, and as my thumb lifted from the trackpad, the entire content below it—the captions, the next image, a block of text—suddenly jumped downward. The image had finally finished loading, but it was taller than the space the browser had reserved for it. The carefully constructed tapestry of the page, which a moment before had felt solid and predictable, now had a noticeable snag in its weave.

In that moment, I wasn't thinking about Core Web Vitals or CLS scores. I was thinking about my friend, looking at the page. I was thinking about the slight disorientation, the subtle loss of trust that comes when the ground shifts under your cursor. That jump was a tiny insult to the user’s attention, a broken thread in the narrative I was trying to build with the page’s flow.

The culprit, once I dug into DevTools, was embarrassingly simple. For one of the image sources in my srcset—a smaller, mobile-targeted version—I had omitted the `width` and `height` attributes. I’d told the browser to be responsive, to pick the right source, but I hadn’t given it the foundational geometry of the image file itself. Without those intrinsic dimensions, the browser couldn’t calculate the aspect ratio until it had downloaded enough of the image to parse its header. So, it saw an `` with no inherent size, assumed a width of 100%, and reserved a height of… zero. It waited, holding a space of nothing, until the pixels arrived and forced a recalculation of everything around it.

Fixing it was trivial. Adding those two numbers, the `width=` and `height=`, felt less like writing code and more like handing the browser a blueprint. I wasn't restricting the image’s final rendered size with CSS; I was giving the layout engine a heads-up. “This is the shape of the thing that’s coming,” I was saying. “Plan for this.” The next scroll was silent. The page settled like a stone. The jump was gone.

That specific, quiet failure taught me more about layout stability than any dashboard metric ever could. It framed the `size` attributes not as an optional piece of HTML trivia, but as the first, crucial stake in the ground for the browser’s renderer. They are the warp threads on the loom, held taut and measured, upon which every other element is woven. To leave them undefined is to ask for a snag, a pull, a moment where the user feels the machinery grind instead of seeing the seamless cloth. It’s a lesson in giving the browser the courtesy of foresight, so it can extend the same courtesy to the person on the other side of the glass.

Notes & further reading

A few pages I came back to while writing this: