irpas技术客

如何在 React 中优雅的写 CSS?CSS作用域隔离_五虎战画戟_react 样式隔离

irpas 3256

目录

方案一:?namespaces

方案二:CSS in JS

1. styled-jsx

2. styled-components

安装

全局样式

局部(组件)样式

方案三:CSS Modules


用了 React 很久了,关于 react 中 css 作用域隔离一直不爽,这里总结一下在 React 中 优雅的写css。

方案一:namespaces方案二:CSS in JS方案三:CSS Modules

方案一:?namespaces

利用约定好的命名来隔离 CSS 的作用域。这种方式不多加描述,大家都懂。

方案二:CSS in JS

目前的 CSS in JS 的第三方库有60余种,介绍两款我在使用的库

styled-jsxstyled-components 1. styled-jsx

?我在之前的文章中有写过它,你可以参阅

在 create-react-app 中使用 styled-jsx_五虎战画戟-CSDN博客yarn add react-app-rewired customize-cra在 package.json 中替换/* package.json */ "scripts": {- "start": "react-scripts start",+ "start": "react-app-rewired start",- "build": "react-scripts build",+ "build": "react-app-rewired build",- ".https://blog.csdn.net/qq_41887214/article/details/120523661语法:

import React from "react"; export default () => { return ( <div className='container'> <section className='main'> <h1>111111</h1> </section> <style jsx>{` .container { height: 100vh; background: royalblue; } .main { height: 300px; background: #61dafb; } `}</style> </div> ); }

缺点:但是?styled-jsx 的缺点在于,它无法修改第三方UI组件的样式,这让我很痛心。当我要修改第三方UI组件时只能用 css?namespaces 使用

优点:但是优点也很明显,语法和 css 一致,没有学习成本

2. styled-components 安装 npm install --save styled-components 全局样式 // style.js import { createGlobalStyle } from 'styled-components' export const GlobalStyle = createGlobalStyle` html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } `;

项目入口文件index.js中加载全局样式 style.js

import React from 'react'; import ReactDOM from 'react-dom'; import { GlobalStyle} from './style.js'; import App from './App'; ReactDOM.render( <> <GlobalStyle/> <App/> </>, document.getElementById('root') ); 局部(组件)样式

对于一个特定的组件,我们可以事先在render函数中,用组件的命名方式替换原本的div等标签

import React, {Component} from 'react' import { HeaderWrapper, Nav, NavItem } from './style' class Header extends Component { render() { return ( <HeaderWrapper> <Nav> <NavItem className='left active'>首页</NavItem> <NavItem className='left'>下载App</NavItem> <NavItem className='right'>登陆</NavItem> <NavItem className='right'> <span className='icon'>😄😄</span> </NavItem> </Nav> </HeaderWrapper> ) } } export default Header

然后在同目录下的style.js中编写具体的CSS样式,以组件名的形式导出

import styled from 'styled-components' export const HeaderWrapper = styled.div` position: relative; margin: 0; padding: 0; height: 58px; border-bottom: 1px solid #f0f0f0 `; export const Nav = styled.div` width: 945px; height: 100%; padding-right: 70px; box-sizing: border-box; margin: 0 auto; display: flex; justify-content: space-around; ` export const NavItem = styled.div` line-height: 56px; padding: 0 15px; font-size: 17px; color: #333; `

缺点:

1.?jsx 中的原生标签不能一眼看出来,额外增加了标签变量

2. 使用不方便,与平时html + css 开发习惯相差较大

3. 也不能用来修改第三方组件样式

优点:

1. 样式写在 js 文件里,降低 js 对 css 文件的依赖。

2. 样式可以使用变量,更加灵活。

3. 使用方便,不需要配置 webpack、开箱即用。

4. SSR 类框架处理 CSS Modules 变量相当棘手,所以使用 styled-components 作方案

方案三:CSS Modules

利用?webpack?等构建工具使 class 作用域为局部。CSS 依然是还是 CSS

npm i -D style-loader css-loader

webpack.config.js

module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true, }, }, ], }, ], }, };

modules 更具体的配置项参考:css-loader | webpack 中文文档

loader 会用唯一的标识符 (identifier) 来替换局部选择器。所选择的唯一标识符以模块形式暴露出去。

webpack.config.js

module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { mode: 'local', // 样式名规则配置 localIdentName: '[name]__[local]--[hash:base64:5]', }, }, }, ], }, ], }, };

App.js

... import styles from "./App.css"; ... <div> <header className={styles["header__wrapper"]}> <h1 className={styles["title"]}>标题</h1> <div className={styles["sub-title"]}>描述</div> </header> </div>

App.css

.header__wrapper { text-align: center; } .title { color: gray; font-size: 34px; font-weight: bold; } .sub-title { color: green; font-size: 16px; }

编译后的 CSS,class?增加了 hash 值。

.App__header__wrapper--2_jgY { text-align: center; } .App__title--GpMto { color: gray; font-size: 34px; font-weight: bold; } .App__sub-title--1cIFi { color: green; font-size: 16px; }

优点:解决了css局部作用域和模块依赖, 没有改造CSS,上手成本小,简单易用

缺点:对于不会webpack配置的同学有一定起步成本,但你可以参考我的webapck专栏教程https://blog.csdn.net/qq_41887214/category_10668880.html

参阅:

CSS Modules 用法教程 - 阮一峰的网络日志


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #React #样式隔离 #用了 #很久了关于 # #CSS