Blog

CSS :has() — The Parent That Knows What's Happening Inside

A form field should highlight red when the input inside it is invalid. Simple enough — except CSS spent 25 years unable to ask an element about what's happening inside it, only the reverse. I look at how :has() flips that direction, how it differs from ordinary combinators, and where this new power genuinely costs you performance.

Container Queries: A Component That Knows Its Container, Not the Viewport

The same product card looks great in a grid and falls apart in a narrow sidebar — despite carefully tuned media queries. The problem isn't in your code, it's in the question a media query asks: about screen width, not about the space the component actually got. I look at how container queries move that question to where it should have been asked all along, and what actually happens under the hood when an element becomes a 'query container.'

Building Accessible Components for Screen Readers

Correct HTML is only the starting point. See how the accessibility tree actually works, why ARIA does more harm than good more often than you'd think, and build a real accordion, a live region, and Next.js focus handling with me.

Animated Microinteractions in Ecommerce

Two stores, the same product, the same server response time – yet one feels faster and more trustworthy. The difference comes down to microinteractions: a few hundred milliseconds of animation that decide whether a user trusts what's on screen. I break them down from first principles – the trigger/feedback model, what actually happens inside the browser's rendering engine, and prefers-reduced-motion.