Using CSS Modules In Your React App
Adding CSS is necessary to style your React application, but without a strictly enforced styling convention, it will be harder to maintain and your project over time. You could adopt the BEM notation. However, writing out all the different class names becomes verbose as more components are added. This is where using CSS modules in your React application is helpful. Having class names be locally scoped to each component prevents conflicting styles as project complexity increases.
Before CSS Modules In Your React App
Prior to CSS modules, we had to ensure the CSS can be maintained as a project gets larger. The BEM notation is helpful because is provides a way for you to structure and maintain large amounts of CSS. Consider an example of a card:
/* card.css */.card {height: 60rem;width: 40rem;}.card--light {background-color: #fff;}.card--hover:hover {opacity: 0.5;}.card--dark {background-color: #000;}.card__title {font-size: 4rem;}.card__title--bold {font-weight: 600;}.card__description {font-size: 2rem;}.card__description--italic {font-style: italic;}
Your HTML may look something like this:
<div class="card card--light card--hover"><h3 class="card__title card__title--bold">Card Title</h3><p class="card__description card__description--italic">Description of the card</p></div>
Although this works, class names can get lengthy over time and the HTML can become harder to read. Imagine having the class name span three or more lines. Once you take up the card class name, you have to make sure you don't use it again. What if you had components such as: FloatingCard, MediaCard, or HorizontalCard? How would the CSS and HTML look? You may find yourself eventually having to become quite creative with your class names. Here's an example of how the HTML could look like with the BEM notation:
<div class="floating-card floating-card--light floating-card--hover"><h3 class="floating-card__title floating-card__title--bold">Floating Card Title</h3><p class="floating-card__description floating-card__description--italic">Description of the floating card</p></div><div class="media-card media-card--light media-card--hover"><h3 class="media-card__title media-card__title--bold">Media Card Title</h3><p class="media-card__description media-card__description--italic">Description of the media card</p></div><div class="horizontal-card horizontal-card--light horizontal-card--hover"><h3 class="horizontal-card__title horizontal-card__title--bold">Horizontal Card Title</h3><p class="horizontal-card__description horizontal-card__description--italic">Description of the horizontal card</p></div>
Notice that there is a lot of repeated typing. And as we want to add more styles, the class name can get larger, making it harder to read and maintain.
What Does CSS Modules In Your React App Do?
CSS Modules creates a unique class name for your generated HTML. This is useful so that we can use the same class name throughout different components in your React application without having to worry about conflicting styles.
To use CSS modules in a create-react-app project, you can name the file with the .module.css extension. In the previous question about implementing different types of cards, using CSS modules, you can reuse class names and instead do something like this:
FloatingCardComponent
/* floating-card.module.css */.card {/* Code goes here */}.title {/* Code goes here */}.description {/* Code goes here */}
// floating-card.component.jsximport styles from "./floating-card.module.css";const FloatingCard = () => {return (<div className={styles.card}><h3 className={styles.title}>Floating Card Title</h3><p className={styles.description}>Description for floating card</p></div>);};
MediaCard Component
/* media-card.module.css */.card {/* Code goes here */}.title {/* Code goes here */}.description {/* Code goes here */}
// media-card.component.jsximport styles from "./media-card.module.css";const MediaCard = () => {return (<div className={styles.card}><h3 className={styles.title}>Media Card Title</h3><p className={styles.description}>Description for media card</p></div>);};
HorizontalCard Component
/* horizontal-card.module.css */.card {/* Code goes here */}.title {/* Code goes here */}.description {/* Code goes here */}
// horizontal-card.component.jsximport styles from "./horizontal-card.module.css";const HorizontalCard = () => {return (<div className={styles.card}><h3 className={styles.title}>Horizontal Card Title</h3><p className={styles.description}>Description for horizontal card</p></div>);};
Conclusion
Using CSS modules, we can reuse the same class name throughout the different components while using the same class name. This makes it easier to maintain CSS code and reduces the amount of repeated typing of class names. CSS modules handles the tedious task of ensuring you have unique class names, so you can spend more time and effort on implementing your designs.