CSS Modules

There are several ways to write styles in React. The most common is CSS modules. This method combines CSS styles with components and applies them directly to components.

| - SRC | | _components | | _ButtonComponent | | _Button. JSX | | _Button) sassCopy the code

Example: CSS mudules in React

You can see that styles applied through modules are all in the form:

Import styles from './GlobalSelectors. CSS '; # 2. Use the form className={styles.container} for the module class name # and the form className="text-left" for the global selector export default class GlobalSelectors extends Component { render() { return ( <div className={ styles.container }> <p className="text-left">Global Selectors</p> </div> ); }} // The CSS file is GlobalSelectors. Css. container {border-width: 2px; border-style: solid; border-color: brown; padding: 0 20px; margin: 0 6px; max-width: 400px; } # ':global' indicates that the class is global. Container: global. text-left {float: left}Copy the code

CSS modules themselves require CSS-Loader to work with them, which may have disadvantages:

  • You must use camelCase to name CSS class names
  • The styles object must be used when imported into className
  • CSS Modules mixed with global CSS classes can be difficult to manage
  • Referencing undefined CSS modules does not get a warning

The React CSS Modules component automatically loads CSS Modules via styleName.

react-css-modules

Using react-CSS-modules will solve the CSS modules problem above, for example:

import React from 'react'; import CSSModules from 'react-css-modules'; Import styles from './tabel.sass' class Table extends React.Component {render() {return (# className = "class name" StyleName indicates the module className <div styleName="table" className="tabel--info"> <div styleName="row"> <div styleName="cell">A0</div> <div styleName="cell">B0</div> </div> </div> ); Export default CSSModules(Table, styles);Copy the code

Concrete implementation steps and notes are discussed below

1. Install

Install via NPM:

npm install --save react-css-modules
Copy the code

2. Webpack configuration

Need to use this bag style – loader | CSS – loader

1. Configure the CSS file

For the development phase:

{test: /\. CSS $/, loaders: [ 'style?sourceMap', 'css?modues&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]' ] }Copy the code

For production: use the 2.x version of the extract-text-webpack-plugin

npm install --save-dev extract-text-webpack-plugin@2 npm install --save-dev resolve-url-loader post-loader // webpack.config.js file var ExtractTextPlugin = require('extract-text-webpack-plugin'); {test: /\. CSS $/, loader: ExtractTextPlugin({notExtractLoader: 'style-loader', loader: 'CSS? modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base4:5]! resolve-url! New ExtractTextPlugin({filename: 'app.css', allChunks: true})]Copy the code

2. For using SASS or other preprocessors

Install the required loader:

NPM install --save-dev resolve-url-loader sass-loader node-sass // sourceMap {test: /\. Sass $/, loaders: [ 'style', 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]', 'resolve-url', } // use sourceMap {test: /\.sass$/, loaders: [ 'style?sourceMap', 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]', 'resolve-url', 'sass?sourceMap' ] }Copy the code

Of course, the production phase configuration is similar

3. Override component styles with ‘styles’

Such as:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return <div styleName='table'>
            <div styleName='row'>
                <div styleName='cell'>A0</div>
                <div styleName='cell'>B0</div>
            </div>
        </div>;
    }
}

export default CSSModules(Table, styles);
Copy the code

This is common. If you want to override styles, you can override the component style using styles in the component:

Import customStyles from './table-custom-styles.css'; <Table styles={customStyles} /> <Table styles={customStyles} />Copy the code

4. Loops and subcomponents

StyleName cannot be used to modify child components within a component, such as:

import React from 'react'; import CSSModules from 'react-css-modules'; import List from './List'; import styles from './table.css'; class CustomList extends React.Component { render () { let itemTemplate; ItemTemplate = (name) => {return <li styleName='item-template'>{name}</li>; }; return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code

This can be rewritten in two ways:

Method 1: Use the styles property

import React from 'react'; import CSSModules from 'react-css-modules'; import List from './List'; import styles from './table.css'; class CustomList extends React.Component { render () { let itemTemplate; # use the styles property ItemTemplate = (name) => {return <li className={this.props. Styles ['item-template']}>{name}</li>; }; return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code

Method 2: Call CSSModules inside the parent component to modify the child component:

import React, {Component} from 'react'; impot CSSModules from 'react-css-modules'; import List from './List'; import styles from './tabel.css'; class CustomList extends Component { render() { let itemTemplate; itemTemplate = (name) => { return <li styleName="item-template">{name}</li>; }; # internal call CSSModules itemTemplate = CSSModules(itemTemplate, this.props. Styles); return <List itemTemplate={itemTemplate} />; } } export default CSSModules(CustomList, styles);Copy the code

5. CSSModules option

CSSModules are written in two ways:

CSSModules(Component, styles, options)

// 或者
CSSModules(Component, styles)
Copy the code

options :

AllowMultiple: The default value is false

If multiple classes are allowed to be declared, false:

<div styleName='foo bar' /> // Error if not allowedCopy the code

2. ErrorWhenNotFount: Default is true,

An error is reported if styleName is not found in CSS modules

6. Use global CSS

:global .foo {
  // ...
}
Copy the code

This is used less often

7. Use the styles attribute for optional class names

We often encounter class names like this:

<div className={this.props.showMsg ? 'msg--visble': 'msg--hidden'}>
</div>
Copy the code

How do you handle this with react-CSS-modules?

The key is that the component decorated with CSSModules inherits the styles property, which maps CSS modules and CSS classes, namely:

class App extends React.Component {
  render() {
    <div>
      <p styleName='foo'></p>
      <p className={this.props.styles.foo}></p>
    </div>
  }
}
Copy the code

In this case,styleName='foo'className={this.props.styles.foo}It’s equivalent!!

So the solution to the above problem is:

class App extends Component { // ... Render () {# let visible = this.props. ShowMsg? 'msg-visible' : 'msg-hidden'; Return (<div # and then use className here instead of styleName # notice that since visible contains characters like '-', Styles ={this.props. Styles [visible]} >... className={this.props. </div> ) } }Copy the code

conclusion

  • react-css-modules github
  • css modules examples
  • Learn how to write className when it changes with events (Rule 7)
  • A way to learn the following writing styles in React
  • How to configure CSS-related loaders in Webpack