React: Using CSS Module Stylesheets

2023-05-02
React.js
Vue.js
CSS
Web Development

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 <button className={styles.error}>Error Button</button>;
}

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 or Whatever.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)