解决css污染问题(CSS Modules) | :global() 、:local()
由于项目创建时,子组件都被导入到了父组件中,而子组件同级的css文件又顺延上去,结果就是各组件之间相同选择器样式在其他组件上全部生效,从而造成组件之间样式相互覆盖.解决方案手动给各个子组件样式文件内容外层包一个统一的属性名,比如子组件名(前提是用sass/less);CSS IN JS: 以js的方式来处理css 。思想是让css有局部作用域,全局作用域这样的区分(推荐方案)CSS IN JS是什
由于项目创建时,子组件都被导入到了父组件中,而子组件同级的css文件又顺延上去,结果就是各组件之间相同选择器样式在其他组件上全部生效,从而造成组件之间样式相互覆盖.
解决方案
- 手动给各个子组件样式文件内容外层包一个统一的属性名,比如子组件名(前提是用sass/less);
- CSS IN JS: 以js的方式来处理css 。思想是让css有
局部作用域
,全局作用域
这样的区分(推荐方案)
CSS IN JS是什么
CSS IN JS是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题
; CSS IN JS 的具体实现有 50 多种,比如:
CSS Modules、
styled-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 在项目中的使用
- 首先创建一个名为index.module.css的样式文件,(这是react中约定的,与普通css区分开)
在要使用的文件中创建样式文件名称
index.module.css
- 在组件中导入样式文件(注意语法)
在要使用的文件在中进行引入
import styles from './index.module.css'
- 通过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>
)
更多推荐
所有评论(0)