Note August 11, 2026 · 1 min

Vue scoped styles leak into child component root elements

Today I learned the hard way: in Vue, a child component's root element receives the parent's data-v-* scoped attribute too. So if your child takes a variant prop and binds it as a class — say hero — and the parent page happens to have a scoped rule for .hero, that rule lands on your component's root.

In my case a BlobField component with variant="hero" got captured by the page's .hero { position: relative; overflow: hidden } section rule, and every blob collapsed into a 280px band at the top of the section.

The fix is boring and absolute: namespace variant classes (v-hero, v-cta) so they can never collide with layout class names. Scoped styles are scoped — except at the one boundary where they aren't.