为何个人样式不起做用?

关于

  • 今天被人问了一个关于react中的样式问题,一瞬间脑壳没反应上来好像还回答错了,有点尴尬水一篇文章记录一下。
  • 问题描述:在一个react父子组件demo中,实际效果与书写的样式不太同样。

问题复现

直接上代码描述问题:javascript

  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;
  1. Parent.less
.parent{
  background-color: blue;
  .component{
    color: white;
  }
}
  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
  1. Child.less
.child{
  background-color: red;
  .component{
    color: black;
  }
}

大概看一下代码,是有一个Parent的父组件,蓝底白字。还有一个Child的子组件,红底黑字
那么实际渲染出的样式是什么样子的呢。以下图:
css

实际看到的效果确实蓝底白字红底白字,为何与写的代码有出入呢。html

究其缘由

  • 为何子组件的字体颜色不是黑色确是白色?

打开调试工具,看到子组件被渲染成一个<div class="component">Child</div> 可是样式却被父组件的样式给覆盖变成了白色,java

缘由:这是由于在w3c 规范中,CSS 始终是「全局的」。在传统的 web 开发中,最为头痛的莫过于处理 CSS 问题。由于全局性,明明定义了样式,但就是不生效,缘由多是被其余样式定义所强制覆盖。react

  • 为何一样.parent .component.child .component是父级覆盖子级?

这就要涉及到浏览器渲染原理css的浏览器解析原则则webpack

浏览器渲染

  1. 浏览器将获取的HTML文档解析成DOM树。
  2. 处理CSS标记,构成层叠样式表模型CSSOM(CSS Object Model)
  3. DOMCSSOM合并为渲染树(rendering tree)将会被建立,表明一系列将被渲染的对象。
  4. 渲染树的每一个元素包含的内容都是计算过的,它被称之为布局layout。浏览器使用一种流式处理的方法,只须要一次绘制操做就能够布局全部的元素。
  5. 将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting

须要注意的是,以上五个步骤并不必定一次性顺序完成,好比DOM或CSSOM被修改时,亦或是哪一个过程会重复执行,这样才能计算出哪些像素须要在屏幕上进行从新渲染。而在实际状况中,JavaScript和CSS的某些操做每每会屡次修改DOM或者CSSOM。git

css的浏览器解析原则

看一个例子:github

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

在咱们不知道规则的状况下,咱们是这样猜想的,按照常人的思惟从左到右。先是找到.nav,而后向下匹配全部的h3span标签。若是在向下匹配的过程当中,没有匹配上的则回溯到上一级继续匹配其余子叶结点。web

但实际上,CSS选择器读取顺序是从右到左浏览器

若是是这样的规定的话,仍是上面的例子就变成了,先找到全部的span标签,而后找span标签是h3的,而后再延着h3往上寻找,这时候发现一个选择器的类名为.nav就把这个节点加入结果集;若是一直往上找直到html标签都没找到的话,就放弃这条线,换到另外一个span进行寻找。

那么来看咱们的这个Demo中的结构

<div class="parent">
    <div class="child">
        <div class="component">Child</div>
    </div>
    <div class="component">parent</div>
</div>

浏览器先找到.component往上寻找,发现了.child .component 这时候渲染出样式为黑色,而后接着向上寻找发现了.parent .component发现存在这个CSS规则,因此这时候颜色变成了白色

如何变成正确的颜色

  • 问题找到了,是由于样式覆盖了,那么如何解决这个问题了。这里咱们采用了CSS Modules方案。
  • 什么是CSS Modules?

CSS划分模块,自动为类名后面生成一个hash值保证类名全局惟一。

  • CSS Modules的使用
  1. 使用create-react-app建立项目,修改webpack.config.js

  1. 在组件中使用
// 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>

配置完成以后发现样式类名变成了hash值,这样即保证了类名的惟一不会存在覆盖的问题

最后

相关文章
相关标签/搜索