sass的使用,解决样式污染,样式穿透
在react脚手架中已经有了sass的配置,因此只需要安装sass的依赖包,就可以直接使用sass了
- 安装sass依赖包
npm i sass -D
这里的引入文件解决了样式污染问题,以下有详细说明
- 把
index.css
改成index.module.scss
- 导入
import styles from './index.module.scss'
文件
使用: ` <div className={styles.css类名}></div>`
注意:如果使用了scss,scss中使用图片的绝对路径的时候需要加上~
background-image: url(~assets/login.png);
css-样式污染
目标
了解样式污染的现象及原因;
了解css in js解决方案
问题引入
如果没有使用css modules在Login组件的index.scss
中添加样式
.root {font-size: 100px;}
给Login和Layout组件的根元素都添加.root这个类
发现在Layout
组件中的样式也跟着发生了改变。
原因
在配置路由时,Layout和 Login组件都被导入到项目中,那么组件的样式也就被导入到项目中了。如果组件之间选择器重复,那么一个组件中的样式就会在另一个组件中也生效,从而造成组件之间样式相互覆盖的问题。
解决方案
- 手动处理 (起不同的类名)
CSS IN JS
: 以js的方式来处理css 。思想是让css有局部作用域全局作用域这样的区分
CSS IN JS
- 推荐使用:CSS Modules (React脚手架已集成,可直接使用)下面是使用方法:
css modules-基本使用
步骤
-
改样式文件名。从
xx.scss -> xx.module.scss
(React脚手架中的约定,与普通 CSS 作区分) -
引入使用。
-
组件中导入该样式文件(注意语法)
import styles from './index.module.scss'
-
通过 styles 对象访问对象中的样式名来设置样式
<div className={styles.css类名}></div>
css类名是index.module.scss中定义的类名。
-
示例
原来
- 定义样式 index.css
.root {font-size: 100px;}
- 使用样式
import 'index.css'
<div className="root">div的内容</div>
现在
修改文件名: index.css ----> index.module.css。内部不变
使用样式
import styles from './index.module.css'
<div className={styles.root}>div的内容</div>
原理
CSS Modules 通过自动给 CSS 类名补足类名,保证类名的唯一性,从而避免样式冲突的问题 。
// Login.jsx
import styles from './index.module.css'
console.log(styles)
css module的注意点
类名最好使用驼峰命名,因为最终类名会生成styles
的一个属性
.tabBar {} ---> styles.tabBar
如果使用中划线的命名,需要使用[]语法-不推荐使用
.tab-bar {} ---> styles['tab-bar']
cssModules-维持类名
目标
掌握:global关键字的用法
,能用它来维持原类名,可以解决样式穿透
格式
在xxx.module.scss中,如果希望维持类名,可以使用格式:
:global(.类名)
示例
这样css modules就不会修改掉类名.a了。等价于写在 index.css中
:global(.a) { }
这样css modules就不会修改掉类名.a了, 但是 .aa还是会被修改
.aa :golbal(.a) { }
应用:
覆盖第三方组件的样式(样式穿透)
:global(.ant-btn) {
color: red !important;
}
css modules-最佳实践
- 每个组件的根节点使用 CSSModules 形式的类名( 根元素的类名:
root
) - 其他所有的子节点,都使用普通的 CSS 类名 :global
index.module.scss
// 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>
)
}