问题起源:
css的全局特性:css 全部作为全局样式的形式,容易造成命名冲突
####css 模块化的概念:
css 应该时有它的作用域的,即:
发展的过程
1.在全局作用域问题上,早期的做法:
- OOCSS
- BEM
都是提供一种一种方式模拟健全的作用域规则,本质上还是靠程序员自身的代码规则约束,没有在根本上解决问题。
2.webpack的出现
一切皆模块,将css也是作为模块处理
通过css-loader—local-scope实现的:
webpack配置
1 | loaders: [ |
使用方式:
引入:
1 | import styles from './MyComponent.css'; |
css文件:
1 | :local(.foo){ |
编译成:
1 | .MyComponent__foo___1rJwx { … } |
很明显,:local
表示在局部作用域中使用的类名
在使用css的地方这样写:
1 | import styles from './MyComponent.css'; |
这样:不用在所有的类名添加冗长的前缀来模拟范围,多个组件可以自定义自己的foo和bar标识符,可以大胆修改我们的CSS,不用小心翼翼地怕影响其他页面的元素
重大的突破:
编写可维护的CSS现在是值得提倡的,但不是通过谨慎地准守一个命名约定,而是在开发过程中通过独立的封装
这样也会引发一个问题:
如果大部分的css都需要是全局的,特殊的部分比较少?
引入局部作用域对我们处理CSS有重大的的连锁反应。命名规范,重用模式,潜在的样式抽离,分包等等,都会直接受到这种转变的影响
最终发展为:
在css-loader上通过一个module的标志可以支持CSS Modules
那么webpack官网上讲解的写法:
modules—启用css模块规范
关于写法:
- 如果使用webpack中的modules的配置的话,默认就是scoped的local范围,即在本组件中使用
- 如果需要使用全局的,可以在样式后面跟相应的全局样式,如:
1 | :global(.title1) { |
- 我一直在想的嵌套的
lcoal
写法应该怎么写,发现不能使用
1 | :local(.title .subTitle){ |
会出现警告,这不是正确的写法,但还是会渲染出来
- 官方给出的
1 | :local(.className) { background: red; } |
一开始不理解,但重要的是其原理,
1 | { |
局部的css 类名这些,会渲染出完整的复杂的类名,像下面这样
1 | src-App__subTitle--NDKro |
每当写一个类的时候,类似这样
1 | :local(.className) { background: red; } == .className { background: red; } |
默认就是 local ,webpack会为其添加前述的完整名称
对应的是:
1 | <span className={ styles.title }></span> |
但如果写的是
1 | :global(.className) { background: red; } |
渲染在页面上只是保留原有的名称,.className
对应的就是:
1 | <span className="title"></span> |
所以解析一下这句代码:
1 | :local .className .subClass :global(.global-class-name) { color: blue; } |
1 | :local(.title){ |
上面的解析就是: 找到局部的 title, 下面的局部的subTitle, 下面的局部的title1,将相应的元素的样式设置成blue
但是如果是 上面写样式的第二种写法:
1 | <span className="title"></span> |
意思是直接使用的全局的样式
其实,我觉得,更合理的写法,不应该将全局和局部的样式写在一起,应该全局一个文件,局部一个文件,分别引入这样更合理一些,在局部样式种夹杂更多的全局样式,会比较混乱。
css module 里的嵌套
使用composes
下面的例子是官网上的:
1 | :local(.continueButton) { |
1 | :local(.nameEdit) { |
引入多个:
1 | :local(.className) { |