What is the difference between module and scoped styles in Vue?
Asked Answered
V

2

29

What is the difference between <style module> and <style scoped> in Vue?

The official documentation (link1, link2) states only that scoped uses PostCSS transformation and module uses CSS Modules. But what is the real functional difference between the two?

(Note: If the PostCSS transformation they use is that plugin, it actually uses CSS Modules...)

Vancouver answered 22/5, 2018 at 9:23 Comment(0)
I
46

They're both ways of handling scoped CSS and do pretty much the same thing. The way they handle it is a bit different though.

Scoped styles in Vue is just normal CSS but with some additional classes added scoping. It's similar to the shadow DOM in that it will scope things out to a component. The benefit of this approach is you carry on writing CSS how you usually do but you get some additional scoping if that's what you want.

CSS Modules is different in that it uses Webpack to compile unique class names based on the block and class. It's kind of automatically creating unique BEM classes. It has a lot of additional functionality above CSS (which you don't have to use).

CSS Modules is not a Vue specific thing so if you learnt that you could apply it to any build where you can import CSS Modules. However Vue CSS scoping is so simple that there isn't really anything additional to learn if you know CSS (a couple of selectors is all really).

CSS Modules classes will be built by webpack as .{component}__{className}__{randomHash}.

Scoped Vue CSS will be built by postcss as .{className}[data-v-{componentHash}]. The componentHash is applied to every element in that component.

Both methods are compiling CSS based on hashes and class names. Scoped CSS is also adding additional data attributes to the HTML for it's scoping. CSS Modules is using javascript a bit more to manage styles.

They're both doing pretty much the same thing though and for me the only real difference is how the classes are created. I guess CSS Modules should be more performant due to the lower specificity of all classes but it will really depend on the person writing the CSS. In my personal opinion I would stick with the simpler one (I'll leave you to decide which one that is)

Immunology answered 22/5, 2018 at 10:14 Comment(6)
Okay, so functionally they are more or less equivalent. Still, from your answer I don't get a clear view of how "they handle it a bit different".Vancouver
I've added a bit more info on the structure of the classes and how they're builtImmunology
Thanks. I did also some reading on my own. The other significant difference you didn't explain in detail is how you apply classes in HTML. In CSSModules you need to use JavaScript objects with bindings (`:class="$style.className"), while in Scoped styles you apply class regulary (class="className").Vancouver
I'd add that one big issue with scoped styles can be using external libraries or global styles. The class you use in a component is passed along as is. So an innocent .wrapper[data-v-54321] class would also have any CSS applied that a global/external .wrapper class has. Which often is a display value and… well, fun times ahead! :DHydraulics
adding to @HerrSiering's point - there's also a case if you are developing a shared component and want to make it a black box for style overrides: CSS modules will obfuscate your classes that will be much harder to select/override for consumersEocene
Aside from everything else, there could be an argument made that scoping your styling by using CSS modules may allow for better portability, esp in the case of converting a component to different frameworks (e.g. Vue to React or vice-versa).Creative
S
3

Module is a safer option for scoping CSS than Scoped

Scoped. In thise mode your CSS class is appended with a data-v attribute like this .button[data-v-9ad5ab0c]. (data-v attribute being added to your html element by Vue).

So the specificity of the applyed styles are higher, but at the same time, if somewhere else in your code there are styles for the .button class, they will be applied as well (assuming they are not overriden by the styles applied to the .button[data-v-9ad5ab0c]).

Module. In this mode your .button class is modified with a hash to something like ._button_vdpj6_2.

This way you get a unique class for your element that won't affect any other elements with class .button. And styles for .button won't affect the element you're styling.

Stupidity answered 10/11, 2023 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.