“This is the seventh day of my participation in the First Challenge 2022.

This article mainly introduces various CSS solutions, including BEM, CSS Modules, CSS in Js, preprocessor, Shadow DOM. Vue Scoped analyzes the background, benefits and problems of various solutions to help people determine which solution is suitable for their own projects

Zero: The native problem of CSS

Before we look at the various solutions, let’s review some of the CSS problems we encounter in daily development. With these problems in mind, we’ll look at the various solutions and see if they can solve the following problems

0.1 No scoped style contamination

One of the things that people criticize about CSS is that it has no local scope and all declared styles are global styles.

In other words, any element on the page that matches a selector’s rule will be applied and cascading between the rules.

This problem becomes even more acute as SPA applications become popular, because for SPA applications all page style code is loaded into the same environment, and the probability of style conflicts is greatly increased. Because of this problem, we encounter the following problems in our daily development:

  • It’s hard to name a selectorTo avoid conflicts with the styles of other elements on the page, we need to be careful when choosing selector names that are not too generic. For example, suppose you define a name for a DOM node on a page that serves as a title.titleThe class name is likely to conflict with or will conflict with other selectors on the page, so you have tomanualAdd some prefixes to the class name, for example.home-page-titleTo avoid this problem
  • Difficulty with teamwork: When multiple people are working on the same project, especially when multiple branches are working on it at the same time, there may be conflicting selector names, but this problem is rarely found in local indie development. When everyone’s code is merged into the same branch, some style problems arise

0.2 Useless CSS style stack

Those of you who have worked on large Web projects have experienced this: When developing new features or refactoring code, there is no explicit one-to-one correspondence between HTML code and CSS styles, so it is difficult to identify which CSS styles are useful and which are not, which makes it difficult to remove potentially useless styles from your code. This way, over time, CSS styles in the project will only increase in stylesheets, not decrease. Useless style code accumulation can lead to the following problems:

  • Projects become more heavyweight: more AND more CSS styles are loaded into the browser, which can have a performance impact
  • Development costs are getting higher: developers find it difficult to understand the style code in their projects, and can even be intimidated by the amount of style code, leading to reduced development efficiency and some bizarre style problems

0.3 State-based style definition

For SPA applications, especially for pages with complex interactions, the style of the page often changes depending on the state of the component

The most common approach is to define different classnames with different states. This solution code seems redundant and tedious, and usually requires changing both the JS code and the CSS code

This CSS rewrite is faster than modifying old files, such an idea almost everyone has had, ALTHOUGH CSS seems to be simple, but the above problems are easy to write write appeared, this is not in advance to choose a good plan

A, the BEM

1.1 introduction

BEM is a CSS naming methodology that stands for Block, Element, or Modifier

This naming method makes CSS easy to unify team development specifications and easy to maintain

Block__element –modifier or block-name__element-name–modifier-name, the name has meaning, that is, the module name + the element name + the modifier name

Such as dropdown can – menu__item – active

The community in the face of BEM naming commendatory or negative, but basically agree with its idea, so you can use its idea, not necessarily use its way of naming

1.2 Application Scenarios

The IDEA of BEM is commonly used with component libraries and with preprocessors such as LESS in business code

1.3 Advantages and Disadvantages analysis

Advantages:

  1. The problem of non-scoped style contamination can be solved by artificially strict adherence to the BEM specification
  2. Good readability, at a glance is that DOM node, for useless CSS to delete, delete the corresponding DOM node, the corresponding CSS can be relatively relieved to delete, will not affect the style of other elements

disadvantages

  1. Naming is too long (personal development habits, some people will find it, I think it improves readability, solves some problems, not a disadvantage), and as for size increase, GZIP is negligible

Personally, I prefer BEM, its idea of coding benefits far outweigh disadvantages, interested in the project can be used, more can see: how to view CSS BEM naming way?

Second, the CSS modules

2.1 introduction

What are CSS Modules?

As the name implies, CSS-modules modularize CSS code to avoid contamination of the module style and make it easy to reuse CSS code

According to the CSS Modules project on Gihub, it is interpreted as:

All class names and animation names have their own scoped CSS files by default.

So CSS Modules are neither an official standard nor a browser feature, but rather a way of scoping CSS class names and selectors (similar to namespaces) in the build step (e.g., using Webpack, remember CSS-loader)

Rely on Webpack CSS-loader, configure as follows, now Webpack has CSS Modules enabled by default

{
    test: /.css$/,
    loader: "style-loader! css-loader? modules"
}
Copy the code

Let’s start with an example:

After importing the style. CSS file as a style object, use the title class as style.title:

import style from './style.css';

export default() = > {return (
    <p className={style.title}>
      I am KaSong.
    </p>
  );
};
Copy the code

The corresponding style. CSS:

.title {
  color: red;
}
Copy the code

The packaging tool compiles style.title to a hashed string

<h1 class="_3zyde4l1yATCOkgn-DBWEL">
  Hello World
</h1>
Copy the code

Style.css will also compile:

._3zyde4l1yATCOkgn-DBWEL {
  color: red;
}
Copy the code

This creates a unique class that solves the problem of CSS modularity

Using CSS Modules is like adding :local to each class name to localize the style. If you want to switch to global mode, use the corresponding :global.

The difference between :local and :global is that CSS Modules only use the localIdentName rule for the class style of the :local block

.title {
  color: red;
}

:global(.title) {
  color: green;
}
Copy the code

As you can see, CSS is still used, but JS is used to manage style dependencies, maximizing the integration of the existing CSS ecosystem and JS modularity, and still compiling separate JS and CSS at release time

2.2 Advantages and disadvantages analysis

advantages

  • 100% solution to CSS non-scoped style contamination
  • Low learning cost: THE API is so simple that it costs almost nothing to learn

disadvantages

  • There is no traditional development process if you don’t want to type too muchstyles.**[react-CSs-modules](Gajus/react – CSS – modules, making), which takes the form of higher-order functions to avoid repeated inputstyles.**
  • No variables, usually combined with a preprocessor
  • The code readability is poor, and the hash value is inconvenient to debug

CSS modules are usually used in React with preprocessors such as LESS. For more details, see CSS Modules and react

CSS in JS

3.1 introduction

CSS in JS is a design pattern introduced in 2014. Its core idea is to write CSS directly to its own components, that is, to write CSS in JS instead of a separate style file

This is different from traditional front-end development thinking, where the principle is separation of concerns, as usual no in-line styling, no in-line scripting, like this code

<h1 style="color:red; font-size:46px;"  onclick="alert('Hi')">
  Hello World
</h1>
Copy the code

Css-in-js is not a new technology, but its popularity in China is not very high. It was first introduced because of the popularity of component-based Web frameworks such as React, Vue and Angular. It also makes developers want to encapsulate component CSS styles into components to solve a number of problems with native CSS writing

Css-in-js is the most popular in the React community. React doesn’t care how users style components. Vue and Angular have their own styles

The above example is rewritten using React as follows

const style = {
  'color': 'red'.'fontSize': '46px'
};

const clickHandler = () = > alert('hi'); 

ReactDOM.render(
  <h1 style={style} onclick={clickHandler}>
     Hello, world!
  </h1>.document.getElementById('example'));Copy the code

The above code is in a file that encapsulates structure, style, and logic, completely violating the “separation of concerns” principle

However, this facilitates component isolation. Each component contains all the necessary code, independent of external, no coupling between components, easy to reuse. So, as React became popular and the component model became popular, this new way of writing “mixed concerns” became mainstream

3.2 Implementation of CSS in JS library summary

There are many libraries that implement CSS-in-JS, more than 61 by one count. Although each library solves the same problem, their implementations and syntax are quite different

There are two kinds of implementation methods:

  • Unique CSS selector, on behalf of library:styled-components
  • Inline style(Unique Selector VS Inline Styles)

In addition to the differences in the generated CSS style and syntax, different CSS in JS implementations implement different functions. In addition to some of the most basic functions such as CSS local scope, the following functions are included in some implementations but not supported:

  • Automatically generates the browser engine prefix – built-in vendor Prefix
  • Support extraction of separate CSS stylesheets – EXTRACT CSS file
  • Built-in support for animations
  • Pseudo classes – pseudo classes
  • Media query – media query
  • other

3.3 styled-componentsThe sample

Styled- Components is the most popular library for CSS in JS, and github has a star rating of over 35K so far

Using styled Components, you can use ES6’s Tagged Templates to define a set of CSS properties for the Component that needs to be styled

Styled Components dynamically generates a CSS selector when the component’s JS code is parsed and executed, and inserts the corresponding CSS style into the head tag as a style tag. Dynamically generated CSS selectors have a small set of hash values to ensure global uniqueness and avoid style collisions

CSS-in-JS PlaygroundCss-in-js is a quick way to try out different IMPLEMENTATIONS of CSS-in-JSstyled-componentsExample of implementing a form:

As can be seen from the above example, styled Components do not require you to set a style name for the DOM node that needs styling. After using the tag template string definition, you will get a Styled Component, which can be used directly in JSX

You can see in the screenshot that the style is generated by the boxHash valueTo achieve theLocal CSS scopeScoping styles,The styles of the components do not clash

3.4 RadiumThe sample

The biggest difference between Radium and Styled – Components is that it generates inline styles for tags.

Because tag inline style in handling such as media Query and :hover, :focus, :active and browser state related style is very inconvenient, so Radium for these styles encapsulate some standard interface and abstraction

Here’s another example of Radium’s CSS-in-JS Playground:

As can be seen from the above exampleradiumDefine the syntax and stylestyled-componentsThere is a big difference and it requires you to use itstyleProperties forDOMAdd the appropriate styles

Inline styles are generated directly within the tag. Inline styles have the following advantages over CSS selectors: they have the effect of local style scope, and no additional operations are required

CSS in JS with “CSS preprocessor “(e.g. Less and CSS preprocessorSass, including PostCSS) what’s the difference

CSS in JS Uses JavaScript syntax, is a part of JavaScript scripts, do not have to learn a set of special API from scratch, there is no more than a compilation step, but usually at run time to dynamically generate CSS, resulting in a certain runtime overhead

3.6 Advantages and Disadvantages

advantages

  • There are no scope-free style contamination problems

    Resolve this with a unique CSS selector or inline style

  • There are no useless CSS style stacks

    Css-in-js binds styles to components. When a component is to be removed, it simply removes the code, without worrying about how the deleted style code will affect the styles of other components in the project. And because CSS is written in JavaScript, we can also use JS explicit variable definitions, module references and other language features to track the use of style, which greatly facilitates the change or reconstruction of style code

  • Better state-based style definitions

    Css-in-js will directly write CSS styles in JS files, so style reuse and logical judgment is very convenient

Disadvantages:

  • Certain learning costs

  • Poor code readability

    Most CSS-in-JS implementations achieve THE effect of CSS local scope by generating a unique CSS selector. These automatically generated selectors can greatly reduce the readability of code and have an impact on developer debug

  • Runtime consumption

    Most CSS-in-JS libraries generate CSS on the fly. This has two effects. First, the code you send to the client will include the CSS-in-JS runtime code used. This code is generally not small, for example, styled- Components runtime size is 12.42kB min + gzip. If you want your first screen to be small, You have to think about it. Second, most CSS-in-JS implementations generate CSS dynamically on the client side, which means there is a performance cost. This tool allows you to view and measure the performance of different CSS-in-JS implementations due to their different implementation details

  • Can’t be combined with mature CSS preprocessors (or post-processors) Sass/Less/PostCSS, :hover and :active pseudo-classes to be complex to handle

It can be seen that there are many advantages, many disadvantages, the choice should be careful, more can read the introduction of CSS in JS written by Ruan Yifeng teacher, know the good and bad of CSS in JS

4. Preprocessor

4.1 introduction

CSS preprocessor is a program that lets you go through the preprocessor’s own unique syntax

There are many CSS preprocessors available on the market, and most CSS preprocessors add features that native CSS does not, for example

  • Code mixed
  • Nested selectors
  • Inheritance selector

These features make CSS structures more readable and maintainable

To use the CSS preprocessor, you must install the CSS compilation tool in your Web service

Our common preprocessors:

  • Sass
  • LESS
  • Stylus
  • PostCSS

4.2 Advantages and Disadvantages analysis

Advantages:

  1. The problem of non-scoped style contamination can be solved by using nesting to strictly observe the inconsistency of the nested first class name
  2. Good readability, at a glance is that DOM node, for useless CSS to delete, delete the corresponding DOM node, the corresponding CSS can be relatively relieved to delete, will not affect the style of other elements

disadvantages

  1. Need to use the relevant compilation tools to handle

Preprocessor is a necessity in modern Web development. Combining with BEM specification, using preprocessor can greatly improve development efficiency, readability and reusability

Five, the Shadow of the DOM

5.1 introduction

Be familiar withweb ComponentsMust knowShadow DOMStyle isolation can be implemented, supported natively by the browser

We often see Shadow DOM in the microfront-end space, so create a sub-application

const shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
shadow.innerHTML = '<sub-app>Here is some new text</sub-app><link rel="stylesheet" href="//unpkg.com/antd/antd.min.css">';
Copy the code

Since the style scope of the child application is only under the shadow element, if the runtime in the child application goes out of bounds to build the DOM, the DOM built will not be able to apply the style of the child application.

For example, the ANTD Modal component is called in the sub-App. Because modal is dynamically mounted to document.body, and because of the Shadow DOM nature, antD styles only work in the Shadow scope. The result is that pop-ups cannot be applied to antD styles. The solution is to float the ANTD style up one level and drop it into the main document, but doing so means that the child application’s style is leaked directly into the main document

5.2 Advantages and Disadvantages analysis

advantages

  • Browser native support
  • Strict style isolation, such as iframe

disadvantages

  • Browser Compatibility Issues
  • Works only on a limited range of DOM structures, as illustrated in the micro-front-end scenario above

For general business development, we still use frameworks such as Vue and React. The Shadow DOM is suitable for special scenarios, such as micro front ends

Six, vue scoped

When a

Use PostCSS to implement the following transformations:

<style scoped>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>
Copy the code

Conversion result:

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>
Copy the code

With scoped, the style of the parent component does not permeate into the child components

However, the root node of a child component is affected by both its parent’s Scoped CSS and the child’s scoped CSS. This is designed so that the parent component can adjust the style of the root element of its child component from a layout perspective, and the parent price influences the style of the child component using the depth-effect selector

You can use the >>> operator:

<style scoped>
.a >>> .b { / *... * / }
</style>
Copy the code

The above code will compile to:

.a[data-v-f3f3eg9] .b { /* ... */ }
Copy the code

Some preprocessors like Sass don’t parse >>> correctly. In this case you can use the /deep/ or ::v-deep operators instead — both are aliases for >>> and work just as well

conclusion

The six schemes are compared as follows, the common style isolation scheme of the community, the following two

  • BEM+ preprocessor
  • CSS Moduls + preprocessor

What is the CSS isolation scheme you use?

Written in the end

This article started on Zxyue25 /github/blog, welcome to follow, STAR ~, continue to record original, good article ~