DEV Community

Cover image for Scoped Styling and the History of CSS Scoping
NickdeK
NickdeK

Posted on

Scoped Styling and the History of CSS Scoping

In my frontend development career of more than 10 years now (jeez, I’m old), I’ve come across a lot of frameworks, libraries, and languages. Recently, I had a discussion with some coworkers about why we should actually use Vue’s scoped styling feature. I figured it would be a good idea to write it down for future reference, and as my first blog post.

The scope of the discussion

The conversation started when I began working on a few projects that used SCSS with Quasar in Vue. None of the components used scoped styling. Instead, everything followed the BEM naming convention. It worked, but in my opinion, it was cumbersome. I was used to simply adding the scoped attribute to the <style> tag, no need for BEM, and I never had issues with styling bleeding into other parts of the build.

So that sparked a discussion: why were we still using these relics of the past in modern projects? Let me explain what my arguments were.

BEM

BEM (Block Element Modifier) was introduced in 2005, and I (kind of) started using it about five years later. It was created to solve a problem: in large projects, styling would unintentionally bleed into unrelated parts of the site. Scenarios like two developers using the same class name in different features were common, often resulting in styling bugs after merging code.

BEM introduced a structured naming convention based on blocks, elements, and modifiers, for example: .form-input--disabled. This helped reduce conflicts by encouraging unique, descriptive class names. More importantly, it forced developers to think about naming in a consistent and predictable way.

At the time, it worked well to reduce bugs and styling collisions. But personally, it never really clicked for me. While the concept made sense, in practice, I often struggled with deciding on names. It also added cognitive overhead, one more thing to remember and enforce.

Component driven development

About 7 or 8 years ago, I started working professionally with modern frontend frameworks. At the time, Polymer was gaining traction, and since it came from Google, my tech lead decided we’d give it a try. Polymer was Google’s vision for Web Components, and you could argue that it helped shape the standards we have today.

Like Web Components, Polymer used the Shadow DOM to render components. That meant each component had its own isolated DOM and scoped styles. CSS didn’t bleed in or out. And for the first time in my career, I could build five components, all with a .header class, and each would behave completely independently.

It was a revelation. I embraced component-driven development fully. Suddenly, I could build truly reusable components that I could copy and paste between projects and have them “just work” (well, mostly). I no longer had to think about naming things carefully to avoid conflicts. It was amazing.

Of course, it wasn’t perfect. There are cases where global styling is needed, and in the early days of Polymer, it was hard to style inside Shadow DOM boundaries. The ::part selector didn’t exist yet, so we often had to write CSS in JavaScript objects and pass them manually into components.

Scoped styling in Vue

Vue gives us the ability to add a scoped attribute to the <style> tag in single-file components. When you do this, Vue automatically generates a unique attribute (like data-v-xxxxxx) and scopes all your CSS to that component by prefixing selectors with that attribute.

It’s not as elegant as the native Shadow DOM model, but it gets the job done, and with fewer trade-offs. You can still use global styles when needed, and Vue provides the :deep() selector to let you style parts of child components or override library styles.

In my opinion, this eliminates the need for the often complex BEM naming convention. Scoped styles let you use clean, simple class names like .header, .button, or .list-item without worrying about conflicts or global pollution. And for me, that simplicity is very welcoming.

Conclusion

BEM was a great solution for a problem that existed in a different era of frontend development. But frameworks like Vue have changed the game. Scoped styles, whether through Vue’s system or the Shadow DOM, offer a cleaner and more maintainable way to write CSS in a component-based world.

You can still use BEM if it works for your team, but in many cases, scoped styles are simpler, more intuitive, and just as safe. It’s one less thing to think about, and for me that makes quite the difference.

What are your thoughts? Do you use scoped styling all the time or not at all? Please let me know in the comments below, I'm always happy to have some new insights 😊

Top comments (0)