Classnames react module css

Using Multiple Classes With React CSS Modules

When working with CSS modules in React, applying styles from one class is straightforward. But, what about using multiple or nested class selectors? In this post, I will show you how to use multiple classes on one element using CSS modules in React. I will also teach you what to do when you have nested class selectors. If you are using Sass/SCSS modules, I have it covered at the end of the post as well.

Working with Many Classes in CSS Modules

Let’s start by applying styling from a single class in CSS modules. Create a CSS module file — Button.module.css .

.button   background-color: #ffffff;  border: 1px solid #2779e4;  border-radius: 7px;  color: #000000;  font-size: 1rem;  padding: 0.75rem 1.25rem; > 

These are some basic styles to create an outlined button. Import the Button.module.css file in your React component and apply the button styling.

import React from 'react'; import styles from './Button.module.css';  export default function Button()   return (  button className=styles.button> type="button">  Click me  button>  ); > 

Thanks to how CSS modules work, the styles.button will apply a unique value to className attribute of the button element. Because of that, the styles for .button selector coming from Button.module.css won’t clash with other styles in the project if they also use a .button selector. Now let’s apply multiple classes from a CSS module to a single element. In this case, let’s create a modifier for the outlined button to make it filled instead.

.button.filled   background-color: #2779e4;  color: #ffffff; > 
div className=`$firstClass> $secondClass> thirdClass fourthClass`>>div> 

If you want to use a value from a variable, you can wrap it around $<> . Otherwise, write it as a string. It might seem like you can throw the modifier class right in there, but it won’t work.

/* ❌ Won't load styles for the 'filled' class in Button.module.css */> button type="button" className=`$styles.button> filled`>>  Click here  button> 

The filled class won’t match the .filled styles defined in Button.module.css . That’s because the filled class coming from CSS modules looks more something like this _filled_gjkwa_3 when rendered in your application. CSS modules work by creating a unique identifier for each class individually, even if the selector chains together multiple classes or nests them. So, to apply multiple CSS modules classes, you have to set the className to use both classes individually.

/* ✅ Will load 'filled' class styles */> button type="button" className=`$styles.button> $styles.filled>`>>  Click here  button> 
.button > .button.filled > .button.filled.active > 
/* 1️⃣ .button */> button className=`$styles.button>`>>1button>  /* 2️⃣ .button.filled */> button className=`$styles.button> $styles.filled>`>>2button>  /* 3️⃣ .button.filled.active */> button className=`$styles.button> $styles.filled> $styles.active>`>>3button> 

Using Nested Classes in CSS Modules

If you have a CSS selector that applies styles to an element only when it is a child of an element with a specific class like so:

.card   background-color: #ffffff;  border: 1px solid #cccccc;  border-radius: 10px;  box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px,  rgba(60, 64, 67, 0.15) 0px 2px 6px 2px; >  .card .body   padding: 1rem 1.25rem; >  .card .header   border-bottom: 1px solid #cccccc;  padding: 1rem 1.25rem; > 

In this case — .header and .body need to have a parent with a .card class. You have to specify the child class on the child element and the parent class on the parent for the styles to work.

import React from 'react'; import styles from './Card.module.scss';  export default function Card()   return (  div className=styles.card>>  div className=styles.header>>  h2>Card Titleh2>  div>  div className=styles.body>>Card Contentdiv>  div>  ); > 

The child styles are applied from styles.header property, although it might seem like they should be nested under styles.card.header instead.

Multiple and Nested Classes in SCSS

.button   background-color: #ffffff;  // ✂️  &.filled   background-color: #a84118;  > > 

This code will apply styles to an element with a .button class and an element with both .button and .filled classes. Using SCSS instead of CSS in CSS modules won’t change the way you apply multiple classes.

import React from 'react'; import styles from './Button.module.scss';  export default function Card()   return (  >  /* .button */>  button className=`$styles.button>`>>Onebutton>  /* .button.filled */>  button className=`$styles.button> $styles.filled>`>>Twobutton>  >  ); > 
.card   // ✂️  .header   // ✂️  >  .body   // ✂️  > > 
import React from 'react'; import styles from './Card.module.scss';  export default function Card()   return (  div className=styles.card>>  div className=styles.header>>  h2>Card Titleh2>  div>  div className=styles.body>>Card Contentdiv>  div>  ); > 

Источник

Using CSS Modules with React

A quick overview of what is CSS Modules, how it works, how it’s used together with React, plus some useful tips.

Poster

What is CSS Modules?

A CSS Modules is a CSS file in which all class names and animation names are scoped locally by default.

CSS Modules is not an official specification nor a standard. It’s a sort of step in CSS/JavaScript building process, which modifies CSS classes by appending some unique hash, thus ensuring, that your CSS styles are locally scoped and don’t overlap with each other.

How does CSS Modules work?

  • CSS styles: compiled CSS with modified class names.
  • JavaScript Object: used to map original class names to modified class names.

Most of the module bundlers, such as webpack, parcel etc support CSS Modules through plugins or loaders.

/* styles.css */ .container  font-size: 16px; // . > /* index.js */ import styles from "./style.css"; //.. element.innerHTML = '+ styles.container + '">'; /* output HTML */ !-- . --> div class="styles_container_g2x5j" /> !-- . --> 

See, how original class name .container was renamed to a .styles_container_g2x5j , in order to scope CSS locally and avoid class name conflicts.

Note: .styles_container_g2x5j is just an example. It’s possible to configure CSS modules compiler class name generation pattern/function.

Using with React

Using CSS Modules in React is really straight forward.

/* Button/styles.css */ .button  // . > /* Button/index.js */ import React from 'react' import styles from './styles.css' const Button = ( children, . props>) => ( button className=styles.button> . props>>children>button> ) 

Multiple classNames

/* App/styles.css */ .container  /* . */ > // Note: you can use dash case class names and access them using styles['is-dark'] in js .isDark  /* . */ > .title  /* . */ > .description  /* . */ > /* App/index.js */ import React from 'react' import styles from './styles.css' const App = () => ( div className=[styles.title, styles.isDark].join(' ')>> h1 className=styles.title>>Titleh1> p className=styles.description>>Descriptionp> div> ) 

Conditional classNames

/* App/styles.css */ .container  /* . */ > .title  /* . */ > .description  /* . */ > // Note: you can use dash case class names and access them using styles['is-dark'] in js .isDark  /* . */ > /* App/index.js */ import React from 'react' import styles from './styles.css' const App = ( isDark >) => ( div className=[styles.container, . (isDark ? styles.isDark : [])].join(' ')>> h1 className=styles.title>>Titleh1> p className=styles.description>>Descriptionp> div> ) 

Simplifying things with “classnames”

Probably, you’ve already noticed that multiple and conditional class names don’t look nice, and seem to a bit overcomplicated.

One way to solve this is to create some utility functions to work with styles object.

However, there’s already such npm package called classnames.

/* App/styles.css */ .container  /* . */ > .isDark  /* . */ > .title  /* . */ > .description  /* . */ > .isUppercase  /* . */ > /* App/index.js */ import React from 'react' import cx from 'classnames' import styles from './styles.css' const App = ( isDark >) => ( div className=cx(styles.container,  [styles.isDark] : isDark >)>> h1 className=styles.title>>Titleh1> p className=cx(styles.description, styles.isUppercase)>>Descriptionp> div> ) 

Simplifying things further with “babel-plugin-react-css-modules”

So far when using classnames npm package code looks much better.

However, it’s still a bit different from what just regular HTML/CSS classes look like when we just write

.

.

There is babel-plugin-react-css-modules which brings back that functionality into CSS Modules.

In short, babel-plugin-react-css-modules transforms styleName to className using compile time CSS module resolution.

Basically, with babel-plugin-react-css-modules, we can provide original class names to a special styleName attribute and plugin replaces them with modified class names in build time.

 /* App/styles.css */ .container  /* . */ > .isDark  /* . */ > .title  /* . */ > .description  /* . */ > .isUppercase  /* . */ > /* App/index.js */ import React from 'react' import cx from 'classnames' import './styles.css' const App = ( isDark >) => ( // Note: that < "isDark": isDark >was simplified to just div styleName=cx('container',  isDark >)>> h1 styleName="title">Titleh1> p styleName=cx('description', 'isUppercase')>>Descriptionp> div> ) 

Conclusion

CSS Modules and React plays very well and, most importantly, solves the issue of having global styles and class name overlapping, while keeping CSS and JS separate.

However, there is another approach for creating locally scoped styles, which is called CSS in JS. There are plenty of implementations/libraries of CSS in JS such as styled-components, emotion, JSS, etc. The choice between CSS Modules and CSS in JS is a matter of preference of a developer or team, and of course, consistency within a project.

Источник

Читайте также:  Php mapping array keys
Оцените статью