Closed xccjk closed 1 year ago
新建组件Page1与Page2,两个组件的根节点className设置为一样
目录结构如下:
src/pages/page1/index.js
import React from 'react' import './index.css' function Page1() { return ( <div className='title'>page1</div> ) } export default Page1
src/pages/page1/index.css
.title { background-color: #ccc; }
src/pages/page2/index.js
import React from 'react' import './index.css' function Page2() { return ( <div className='title'>page2</div> ) } export default Page2
src/pages/page2/index.css
.title { background-color: red; }
src/app.js
import Page1 from './pages/page1'; import Page2 from './pages/page2'; function App() { return ( <div className="App"> <header className="App-header"> <Page1 /> <Page2 /> </header> </div> ); } export default App;
效果图如下:
会发现两个组件之间样式会相互影响?是因为最终打包出来的样式渲染到节点上是这样的:
结论:CSS文件分离 !== CSS作用域隔离
全局污染
命名混乱
代码关系复杂
无法共享变量
复用性差,难维护
行内样式,直接在js中编写css
namespaces
CSS-in-JS,常见的解决方案有styled-components、styled-jsx、react-style
CSS Modules
优点:
缺点:
src/pages/page5/index.js
import React from 'react' function Page5() { return ( <div style={{ background: 'red' }}>page5</div> ) } export default Page5
src/pages/page6/index.js
import React from 'react' function Page6() { return ( <div style={{background: 'green'}}>page6</div> ) } export default Page6
效果图:
通过css样式变量的命令来做到作用域隔离 优点:
src/pages/page7/index.js
import React from 'react' import styles from './index.less' function Page7() { return ( <div className={styles.page7}> page7 <p>哈哈哈,我是通过namespaces方案区分的</p> </div> ) } export default Page7
src/pages/page7/index.less
.page7 { background-color: red; p { font-size: 15px; color: #fff; } }
src/pages/page8/index.js
import React from 'react' import styles from './index.less' function Page8() { return ( <div className={styles.page8}> page8 <p>哈哈哈,我是通过namespaces方案区分的</p> </div> ) } export default Page8
src/pages/page8/index.less
.page8 { background-color: #398def; p { font-size: 30px; } }
通过写js的方式来写css,react官方也是推荐这样来写。官方文档 CSS-in-JS地址,可以看到常见的基于CSS-in-JS的解决方案 优点:
CSS Module本质是通过三方工具如webpack等,把css的变量唯一化 效果图:
从上面可以看出,我设置的类名为styles.header,但是在经过编译后为indexheader2zovj,其实配置一下css-loader开启css modules即可
配置方式:
{ test: /\.css$/, loader: "style-loader!css-loader?modules" }
大功告成!!!
其实css作用域的本质,就是页面中的类名都是唯一的。现在通过编译工具,可以把页面中类名编译为一个唯一的类名,这样就不会出现类名相同的情况下相互影响。
综合下来,CSS Module会比CSS-in-JS使用起来更方便,对代码的入侵更小,写法也更符合常见的形式,结合三方工具配置起来也挺方便的。
场景1
新建组件Page1与Page2,两个组件的根节点className设置为一样
目录结构如下:
src/pages/page1/index.js
src/pages/page1/index.css
src/pages/page2/index.js
src/pages/page2/index.css
src/app.js
效果图如下:
会发现两个组件之间样式会相互影响?是因为最终打包出来的样式渲染到节点上是这样的:
结论:CSS文件分离 !== CSS作用域隔离
CSS的一些常见问题
全局污染
命名混乱
代码关系复杂
无法共享变量
复用性差,难维护
实现CSS样式隔离的几种方式
行内样式,直接在js中编写css
namespaces
CSS-in-JS,常见的解决方案有styled-components、styled-jsx、react-style
CSS Modules
行内样式
优点:
缺点:
src/pages/page5/index.js
src/pages/page6/index.js
效果图:
namespaces
通过css样式变量的命令来做到作用域隔离 优点:
缺点:
src/pages/page7/index.js
src/pages/page7/index.less
src/pages/page8/index.js
src/pages/page8/index.less
效果图:
CSS-in-JS
通过写js的方式来写css,react官方也是推荐这样来写。官方文档 CSS-in-JS地址,可以看到常见的基于CSS-in-JS的解决方案 优点:
缺点:
CSS Module
CSS Module本质是通过三方工具如webpack等,把css的变量唯一化 效果图:
从上面可以看出,我设置的类名为styles.header,但是在经过编译后为indexheader2zovj,其实配置一下css-loader开启css modules即可
配置方式:
大功告成!!!
总结
其实css作用域的本质,就是页面中的类名都是唯一的。现在通过编译工具,可以把页面中类名编译为一个唯一的类名,这样就不会出现类名相同的情况下相互影响。
综合下来,CSS Module会比CSS-in-JS使用起来更方便,对代码的入侵更小,写法也更符合常见的形式,结合三方工具配置起来也挺方便的。