由于项目创建时,子组件都被导入到了父组件中,而子组件同级的css文件又顺延上去,结果就是各组件之间相同选择器样式在其他组件上全部生效,从而造成组件之间样式相互覆盖.

解决方案

  1. 手动给各个子组件样式文件内容外层包一个统一的属性名,比如子组件名(前提是用sass/less);
  2. CSS IN JS: 以js的方式来处理css 。思想是让css有局部作用域,全局作用域这样的区分(推荐方案)

CSS IN JS是什么

CSS IN JS是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题; CSS IN JS 的具体实现有 50 多种,比如:CSS Modulesstyled-components` 等;

Css Modules

css modules 通过对css类名的重命名,保证每一个类名的唯一性,从而避免样式冲突问题

React 推荐使用: CSS Modules (React脚手架已集成,可直接使用)
实现方式: webpack的css-loader插件
react脚手架中演化成: 文件名,类名,hash(随机)三部分,只需要指定类名即可。

在index.module,css中我们写一个类名

.red{

}

通过css modules就会给我们转化成类名

.Button_error_axy4s

Css Modules 在项目中的使用

  1. 首先创建一个名为index.module.css的样式文件,(这是react中约定的,与普通css区分开)

在要使用的文件中创建样式文件名称

index.module.css
  1. 在组件中导入样式文件(注意语法)

在要使用的文件在中进行引入

import styles from './index.module.css'
  1. 通过styles对象访问对象中的样式名来设置样式
<div className={styles.类名}></div>

全局作用域:

我们在写项目的时候,避免不了使用ui组件,想改变全局样式,需要通过全局作用域:global()来进行设置
因为设置的类名已经发生改变,所以在改变组件中的样式时要使用组件中提供的类名

:global(.am-navbar-title){
color:#333;
}
.map{
    padding-top: 45px;
    height: 100%;
}
.container{
    height: 100%;
}
/*在全局样式前面可以加上属于哪个类名之下,这样可以提高权重,避免覆盖组件类名的样式*/


.map :global(.am-navbar){
    margin-top: -45px;
}

局部作用域:

:local(.am-navbar) {
  color: red;
}

CSSModule 用法拓展:

// index.module.scss
.root {
  display: 'block';
  position: 'absolute';
  // 此处,使用 global 包裹其他子节点的类名,这些类名就不会被处理,在 JSX 中使用时,就可以用字符串形式的类名
  // 如果不加 :global ,所有类名就必须添加 styles.title 才可以
  :global {
    .title {
      .text {
      }
      span {
      }
    }
    .login-form { ... }
  }
}

组件内使用时就可以直接写类名:

import styles from './index.module.scss'
const 组件 = () => {
  return (
    {/* (1) 根节点使用 CSSModules 形式的类名( 根元素的类名: `root` )*/}
  	<div className={styles.root}>
      {/* (2) 所有子节点,都使用普通的 CSS 类名*/}
    	<h1 className="title">
      	<span className="text">登录</span>  
      	<span>登录</span>  
      </h1>
			<form className="login-form"></form>
    </div>
  )
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐