CSS规则是全局的,任何组件的样式规则对整个页面都有效。相信写css的人都会遇到样式冲突(污染)的问题。在App.js中我们引入子组件Child和style.cssimportReactfrom'react';importChildfrom'./Child';import'./style.css';constApp=()=>{return(
)}exportdefaultApp;style.css.aaa{背景颜色:red;}然后Child引入了style1.css文件,我们不小心把style1.css中的style写成了aaa。按照预期的结果,App组件中p标签的背景色应该是红色,Child组件中p标签的背景色应该是蓝色。是这样吗?羊毛布?child.jsimportReactfrom'react';import'./style1.css';constChild=()=>{return(
)}exportdefaultChild;style1.css.aaa{background-color:blue;}我们用yarnstart启动项目,可以看到页面上的两个标签都显示为红色。这是因为我们在Appstyle.css中通过这种方式引入了import'./';它的风格在全球范围内发挥作用。如果我们在命名上不注意,很有可能会出现样式名称重复的问题,从而导致上面样式冲突的问题。为了解决全局污染的问题,类名应该长一点嘛,加一层父选择器,减少冲突的几率,那么CSS命名就比较混乱了。CSS模块化的解决方案有很多,但主要分为三大类:(1)标准化CSS命名约定的解决方案如:BEM、OOCSS、AMCSS、SMACSS(2)、CSSinJS完全抛弃CSS,用JavaScript编写CSS规则,styled-components是它的中代表安装npminstall--savestyled-components一般在项目开始的时候,我们都会定义一些初始化样式,这些样式是全局有效的,那么如何使用这个方法来定义这些全局样式呢?最新版本的styled-componentsv4已经将原来的injectGlobal()方法替换为createGlobalStyle(),用法与之前的injectGlobal方法不同。在src下新建一个style.js(注意js后缀不是css后缀,因为我们要在js中写css)1.引入一个新的APIcreateGlobalStyle,在下面新建一个GlobalStyle变量,使用createGlobalStyle方法包裹其中的全局样式(使用反引号字符串包装css样式)import{createGlobalStyle}from'styled-components';exportconstGlobalStyle=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,强,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,字段集,表单,标签,图例,表格,标题,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby??,section,summary,time,标记,音频,视频{保证金:0;填充:0;边界:0;字体大小:100%;字体:继承;垂直对齐:基线;}/*为旧版浏览器重置HTML5显示角色*/article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}body{行高:1;}ol,ul{列表样式:无;}blockquote,q{引号:无;}blockquote:before,blockquote:after,q:before,q:after{content:'';内容:无;}table{边框折叠:折叠;边界间距:0;}`;src/App.js'(一般是最外层的组件),引入刚刚定义的GlobalStyle,然后在render()importReactfrom'react';import{GlobalStyle}from'./风格';从“./common/header”导入标头;functionApp(){return(
);}ex端口默认应用程序;这样引用之后,就可以正常使用全局样式了。以上就是使用styled-components工具定义全局样式的方法,那么如何定义局部样式呢?(这里只介绍最简单的用法,具体请参考官网)在Header组件所在文件夹下,从'styled-components'创建自己的样式文件style.jsimportstyled;exportconstHeaderWrapper=styled.div`position:relative;高度:56px;border-bottom:1pxsolid#f0f0f0;背景:红色;`;上面我们导出了一个labeldiv,这个label有一些样式,使用styled-components之后这个label也变成了一个组件HeaderWrapper已经被导出了,然后我们就可以在Header组件中使用这个组件importReact,{Component}from'react';import{HeaderWrapper}from'./style';classHeaderextendsComponent{render(){return(
111)}}exportdefaultHeader;返回页面,可以看到样式生效了,这样生成的样式名称是随机的,这样就不会出现样式名称的冲突,而且这个标签组件HeaderWrapper只在当前Header组件中使用,所以样式只会在这个Header组件中生效(3),使用JS管理样式模块使用JS编译原生CSS文件,使其具有模块化的能力,代表是CSSModulesCSSModules不做改造CSS融入了编程能力,但是增加了局部作用域和依赖管理,刚好解决了最大的痛点。可以有效避免全局污染和样式冲突,可以最大限度的结合现有的CSS生态和JS模块化能力。webpack自带的css-loader组件自带CSSModules,通过简单配置即可在React脚手架工具中使用,我们通过npmruneject暴露webpack配置文件,找到webpack.config.js文件,在这里添加这句话修改webpack配置,我们需要重启服务,返回页面可以看到这里介绍的样式方法import'./style.css'不起作用;现在我们需要使用importstylesfrom'./style.css';然后使用constApp=()=>{return(
)}也从'react'导入React;import来自Child中'./style1.css'的样式;constChild=()=>{return(
)}exportdefaultChild;刷新页面,可以看到虽然两个文件的样式名称都是aaa,但是现在互不影响了。这是因为CSSModules对CSS中的类名进行了处理,使用对象来存储原始类和混淆类的对应关系。CSSModules自动生成的类名基本是唯一的,大大降低了项目中样式重写冲突的几率。更详细的CSSModule介绍可以参考这篇博客(https://segmentfault.com/a/11...