Before we begin, let’s consider the following three questions:

1. Why style isolation? 2. What are the ways to do style isolation? 3. What do you think is the best way to do style isolation?

All right, let’s get down to business. The following article revolves around the above three problems to explain one by one, let’s begin!

First, why do style isolation


Bullshit, you might say, for resolving style conflicts. Yes, to resolve style conflicts.

So when do style conflicts occur? What is the root cause of style conflicts? Let’s look at a simple example:

Two JSX files, test1 and test2, have the same class name and each reference a CSS style sheet with a modified background color.

/ / the root component
import React from 'react';
import ReactDOM from 'react-dom';
import Test1 from './test1.jsx';
import Test2 from './test2.jsx';
ReactDOM.render(<div><Test1 /><Test2 /></div>.document.getElementById('root'));
Copy the code
// test1.jsx
import React from 'react';
import './test1.scss';
export default const Test1 = () = > <div className="test">Test 1</div>
Copy the code
// test2.jsx
import React from 'react';
import './test2.scss';
export default const Test2 = () = > <div className="test">Test 2</div>
Copy the code
// test1.scss
.test { background: yellow }
Copy the code
// test2.scss
.test { background: yellowgreen }
Copy the code

What will be the background color of the.test element on the final page? Yes, two are chartreuse. The reason is CSS priority, and later styles overwrite the previous ones.

Conclusion: When class names collide, style overrides can occur due to CSS priorities. So we know, to do style isolation, even if the name is the same, do not let it have style overwrite problems. So how do we do that?

What are the ways to do style isolation?


There are many ways to isolate styles, but let’s talk about some of the most common:

1. Line style

Advantages: Absolute style isolation. Disadvantages: officially not recommended, more performance consumption. If you want to use inline style, the recommended inline style library is Redium.

2. css-in-js

Advantages: mainstream scheme. The principle is to generate random hash value assigned to the class name, solving the problem of class name conflict. Disadvantages:

  • ① Writing CSS in JS violates the principle of SEPARATION of JS and CSS.
  • (2) Not friendly to CSS preprocessors.
  • ③ Is not conducive to debugging, can not see the original class name.

Common CSS-IN-JS library: Emotion Styled – Components: This is a CSS-in-JS framework designed for React. When defining a component style, it creates a React component.

3. css modules

CSS Modules are not an official STANDARD for CSS, nor are they a feature of browsers, but rather a way of scoping CSS class names and selectors (similar to namespaces) using build tools such as WebPack. The idea is to make the class name unique by hash.

{
    loader: 'css-loader'.options: {
        modules: true.// Enable modularization
        localIdentName: '[path][name]-[local]-[hash:base64:5]' // Class name name}}Copy the code

Parameters to localIdentName:

  • [path] indicates the path of the style file relative to the project root directory
  • [name] indicates the style file name
  • [local] indicates the name of the class definition
  • [hash:length] indicates the 32-bit hash value. Note: Only class name and ID selectors are modularized, label selectors are not.

Advantages: simple, JS and CSS separation. Disadvantages: Some SCSS advanced classes are unusable, such as if you want to synchronize @include with parent class names and define child class names.

4. scoped style

Similar to Vue’s scoped, local scoped style. The principle is implemented by adding unique custom attributes to the DOM, with styles associated with custom attributes. Advantages: Works well with SCSS and can be developed freely using sASS’s advanced syntax. Disadvantages: None at present.

How to use: Use a plug-in called craco-plugin-scoped-css

yarn add craco-plugin-scoped-css
Copy the code

Create a craco.config.js file:

module.exports = {
  plugins: [{plugin: require('craco-plugin-scoped-css')}}]Copy the code

Let’s do the Babel plugin

yarn add babel-plugin-react-scoped-css --dev
Copy the code

Increase in babelrc

"plugins": ["babel-plugin-react-scoped-css"]
Copy the code

webpack loader

yarn add scoped-css-loader --dev
Copy the code
{
  test: /\.scss$/,
  use: [
    'style-loader'.'css-loader',
    {
      loader: 'postcss-loader'.options: {
        plugins: [require('tailwindcss'), require('autoprefixer')],}}, {loader: 'scoped-css-loader' }, / / here
    {
      loader: 'sass-loader'.options: {
        sourceMap: true.prependData: ` @import "~ddo-assets/styles/mixin.scss"; @import "~ddo-assets/styles/bemMixin.scss"; @import "~ddo-assets/styles/_variables.scss"; `}},],},Copy the code

Third, I think the best practices


Scoped style. Because it can not only solve the separation of JS CSS, solve the problem of class name unique style isolation, but also meet my need to use SCSS advanced syntax to do whatever I want.

As for which kind you like, it depends on your own needs ~

Iv. Recommended relevant excellent documents


  • React Style Management
  • css module