前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么我的样式不起作用?

为什么我的样式不起作用?

作者头像
w候人兮猗
发布2020-07-01 15:31:08
4.1K0
发布2020-07-01 15:31:08
举报

Contents

关于

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

问题复现

直接上代码描述问题:

  1. Parent.js
代码语言:javascript
复制
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
代码语言:javascript
复制
.parent{
  background-color: blue;
  .component{
    color: white;
  }
}
  1. Child.js
代码语言:javascript
复制
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
代码语言:javascript
复制
.child{
  background-color: red;
  .component{
    color: black;
  }
}

大概看一下代码,是有一个Parent的父组件,蓝底白字。还有一个Child的子组件,红底黑字

那么实际渲染出的样式是什么样子的呢。如下图:

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

究其原因

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

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

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

  • 为什么同样.parent .component.child .component是父级覆盖子级?

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

浏览器渲染

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

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

css的浏览器解析原则

看一个例子:

代码语言:javascript
复制
.nav h3 span {font-size: 16px;}

在我们不知道规则的情况下,我们是这样猜测的,按照常人的思维从左到右。先是找到.nav,然后向下匹配所有的h3span标签。如果在向下匹配的过程中,没有匹配上的则回溯到上一级继续匹配其他子叶结点。

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

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

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

代码语言:javascript
复制
<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. 在组件中使用
代码语言:javascript
复制
// 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值,这样即保证了类名的唯一不会存在覆盖的问题

最后

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年9月4日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于
  • 问题复现
  • 究其原因
  • 浏览器渲染
  • css的浏览器解析原则
  • 如何变成正确的颜色
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档