Most large CSS codebases require complex naming schemes to help avoid naming conflicts in the global namespace. CSS Modules address these problems by creating a local scope for all class names in a single CSS file. This file is imported to a JavaScript module, where CSS classes are referenced as strings. Then, in the build pipeline (Webpack, Browserify, etc.), the class names are replaced with generated unique strings. This is a significant change in responsibilities. Previously, a human had to manage the global namespace, to avoid class naming conflicts; now that responsibility rests with the build tooling. A small downside we've encountered with CSS Modules: functional tests are usually out of the local scope and can therefore not reference classes by the name defined in the CSS file. We recommend using IDs or data attributes instead.
Most large CSS codebases require complex naming schemes to help avoid naming conflicts in the global namespace. CSS Modules address these problems by creating a local scope for all class names in a single CSS file. This file is imported to a JavaScript module, where CSS classes are referenced as strings. Then, in the build pipeline (Webpack, Browserify, etc.), the class names are replaced with generated unique strings. This is a significant change in responsibilities. Previously, a human had to manage the global namespace, to avoid class naming conflicts; now that responsibility rests with the build tooling. A small downside we've encountered with CSS Modules: functional tests are usually out of the local scope and can therefore not reference classes by the name defined in the CSS file. We recommend using IDs or data attributes instead.