React: Using CSS Module Stylesheets
What Module CSS
Back when I was working on certain Vue.js projects, the styling came bundled with Vue modules, and was either inherently bound to the module (i.e. in the same file as markup and code), or modularised but still coupled with the markup.
The result was, styles were local to thw component by default (well, "by default" being mostly a scaffolding defaults, but still),
so style classes were automatically getting unique names via adding unique identified to the DOM element and changing style classes from e.g.
.example
into .example[data-v-f3f3eg9]
- so getting a common style actually required some work and consideration.
React is more "manual" in this regard - a lot of code I've seen just includes the CSS (or SCSS) like
import * from ./styles.css
and then using className="MyClassName"
classes in elements.
Which is OK, but it often covers much more ground than needed - so if I'm dealing with several similar components on the page that need different styling (like if the component comes from a package that is used in several sub-components independently), we got ourselves a problem, as whoever defined the styling for the class last, reigns supreme.
And so
There's a way to do things similar to Vue approach: https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
Essentially, it's a way to make CSS class names unique per component instance, so each would have independent styles.
To re-use examples found in React docs, let's say we have styles in Styles.module.css
, and component in Component.js
:
.error { background-color: red; }
and
import React from 'react'; import styles from './Styles.module.css';
const Button = () => { return ; }
export default Button;
What will ensue is className will be unique, e.g. Button_error_ax7yz
, and specific styles will only be applied to this instance.
Caveats
There's a couple of nuances to this:
- Styles file has to have
.module.
in its name -Something.module.css
orWhatever.module.scss
, but.module.
needs to be there. - Class names shouldn't have dashes -
.error
or.errorButton
would work, but.error-button
would not (in my case, IDE tries to be helpful and remove the dash, but it leads nowhere)