本文已参与[新人创作礼]活动,一起开启掘金创作之路
抛出问题
众所周知,vue的scoped是为了让css也有独立的作用域,当前组件写的样式只对当前组件的template生效,而在react中我们该如何让css有独立的作用域呢
样式污染的现象及原因
在配置路由时,多个组件都被导入到项目中,那么组件的样式也就被导入到项目中了,也就是说最终的所有的样式文件全汇集到index.html中了。
如果多个组件的样式中出现选择器重复,那么一个组件中的样式就会在另一个组件中也生效,从而造成组件之间样式相互覆盖的问题。
了解css in js解决方案
-
手动处理: 给每个组件的根元素起不同的类名,确保类名不重复
-
CSS IN JS : 以js的方式来处理css 。通过代码来改动css选择器,让css样式也有局部作用域 全局作用域这样的区分
推荐第二种,即省时又便于后期维护
CSS IN JS
- CSS IN JS:是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题
- CSS IN JSopen in new window 的具体实现有 50 多种,比如:CSS Modules、scoped css, styled-componentsopen in new window 等
- 在vue中默认使用的是scoped css
- 在react中推荐使用:CSS Modulesopen in new window (推荐原因:React脚手架已集成,可直接使用)
CssModules-基本使用
没有使用
css文件
.root {font-size: 100px;}
jsx文件
import 'index.css'
<div className="root">div的内容</div>
使用后
css文件将XXX.css文件改为XXX.module.css
jsx文件
import styles from './index.module.css'
<div className={styles.root}>div的内容</div>
原理
CSS Modules 通过自动给 CSS 类名补足类名,保证类名的唯一性,从而避免样式冲突的问题 。
示范
// .jsx
import styles from './index.module.css'
console.log(styles)
CssModules-维持类名
在没有做任何处理的情况下, 每一个类名都会被修改。如果希望某个类名不被修改,可以使用: global
实践
.jsx
import React from 'react';
import styles from './Layout.module.scss'
function Layout(props) {
return (
<div className={styles.root}>
123
<div className={styles.info}>22</div>
<div className='footer'>32</div>
</div>
);
}
export default Layout;
XXX.module.css
优化
最外层使用一个类名然后保证整个module.css的唯一性,然后其他的类名使用global包裹即可,使用起来即实用又便捷
index.module.scss
.root {
display: 'block';
position: 'absolute';
// 此处,使用 global 包裹其他子节点的类名。此时,这些类名就不会被处理,在 JSX 中使用时,就可以用字符串形式的类名
// 如果不加 :global ,所有类名就必须添加 styles.title 才可以
:global {
.title {
.text {
}
span {
}
}
.login-form { ... }
}
}
jsx文件
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>
)
}