react中sass的使用,解决样式污染,样式穿透
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> ) }
作者:风妮
链接:https://juejin.cn/post/7031556713329197093