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)