about

  • I was asked a question today aboutreactThe style of the problem, the moment the head did not react to come up to seem to answer wrong, a little embarrassed water an article record.
  • Problem description: In areactFather and son componentsdemo“, the actual effect is not quite the same as the written style.

Problem of repetition

Go straight to the code to describe the problem:

  1. Parent.js
import React from 'react';
import Child from './Child'
import './Parent.less'

function Parent() {
  return (
    <div className="parent">
        <Child/>
        <div className='component'>parent</div>
    </div>
  );
}
export default Parent;
Copy the code
  1. Parent.less
.parent{
  background-color: blue;
  .component{
    color: white; }}Copy the code
  1. Child.js
import React from 'react';
import './Child.less'

function Child() {
    return (
        <div className="child">
            <div className='component'>Child</div>
        </div>
    );
}

export default Child
Copy the code
  1. Child.less
.child{
  background-color: red;
  .component{
    color: black; }}Copy the code

If you look at the code, there is a Parent component with white text on a blue background. There is also a Child component for Child, with black text on a red background. So what does the actual render look like? The diagram below:

Actually see the effect of white words on blue background and white words on red background, why with the written code is different.

Investigate its reason

  • Why is the font color of the child component white instead of black?
Child

Why: This is because CSS is always “global” in the W3C specification. In traditional Web development, one of the biggest headaches is dealing with CSS. Because of global, the style is clearly defined, but it does not take effect, possibly because it is overridden by other style definitions.

  • Why the same.parent .component.child .componentDoes the parent overwrite the child?

This involves the principles of browser rendering and the principles of CSS browser parsing

Browser rendering

  1. The browser parses the obtained HTML document into a DOM tree.
  2. Process CSS tags to form a cascading Style sheet modelCSSOM(CSS Object Model).
  3. willDOMandCSSOMMerge into a render tree(rendering tree)Will be created to represent a series of objects that will be rendered.
  4. The content contained in each element of the render tree is computed and is calledLayout of the layout. Browsers use a streaming approach that allows all elements to be laid out in a single draw operation.
  5. To draw the nodes of the render tree onto the screen, this step is called drawingpainting.

It is important to note that the above five steps are not necessarily done all at once in order, such as when the DOM or CSSOM is modified, or which process is repeated in order to work out which pixels need to be rerendered on the screen. In practice, some JavaScript and CSS operations often modify the DOM or CSSOM multiple times.

Browser parsing principles for CSS

Here’s an example:

.nav h3 span {font-size: 16px; }Copy the code

Without knowing the rules, this is how we guess, from left to right in the normal way of thinking. So, you find.nav, and then you go down and match all the H3 and SPAN tags. If there is no match in the process of downward matching, it will go back to the previous level and continue to match other cotyledons.

But in reality, CSS selectors read from right to left

If that’s the rule, then the example above would be, look for all the span tags, look for the span tag that’s H3, and then look up h3, and then find a selector whose class name is.nav and add that node to the result set; If you can’t find an HTML tag until you look up, you can drop the line and go to another span.

So let’s look at the structure in our Demo

<div class="parent">
    <div class="child">
        <div class="component">Child</div>
    </div>
    <div class="component">parent</div>
</div>
Copy the code

The browser looks up at.component, finds.child. component and renders it black, then looks up at.parent. Component and finds this CSS rule, so the color is white

How to get the right color

  • The problem is found because the style is overwritten, so how to solve the problem. Here we use the CSS Modules scheme.

  • What is CSS Modules? The CSS is divided into modules that automatically generate a hash value after the class name to ensure that the class name is globally unique.

  • Use of CSS Modules

  1. usecreate-react-appCreate project, modifywebpack.config.js

  1. Used in components
// parent.js
import styles from './Parent.less'

<div className={styles.parent}>
   <Child/>
   <div className={styles.component}>
    css modules parent
   </div>
</div>  

//child.js
import styles from './Child.less'
<div className={styles.child}>
    <div className={styles.component}>
        css modules child
     </div>
</div>
Copy the code

After the configuration is complete, the style class name is changed to a hash value, which ensures that the unique class name is not overwritten

The last

  • Why Doesn’t My style Work?
  • Reference: Browser rendering principles and procedures
  • Reference: CSS selectors match rules from right to left
  • The DEMO address