css的问题
类名冲突的问题
- 当你写一个 css 类的时候,是写全局的类呢,还是写多个层级选择后的类呢?你会发现怎么都不好;
- 过深的层级不利于编写、阅读、压缩、复用;
- 过浅的层级容易导致类名冲突;
- 一旦样式多起来,这个问题就会变得越发严重,其实归根结底,就是 类名冲突不好解决 的问题;
重复样式
这种问题就更普遍了,一些重复的样式值总是不断的出现在 css 代码中,维护起来极其困难,比如,一个网站的颜色一般就 primary、info、warn、error、success 几种;
如果有更多的颜色,都是从这些色调中自然变化得来,可以想象,这些颜色会到处充斥到诸如背景、文字、边框中,一旦要做颜色调整,是一个非常大的工程;
css 文件细分问题
在大型项目中 css 也需要更细的拆分,这样有利于 css 代码的维护,比如:
- 有一个做轮播图的模块,它不仅需要依赖 js 功能,还需要依赖 css 样式,既然依赖的 js 功能仅关心轮播图,那 css 样式也应该仅关心轮播图;
- 由此类推,不同的功能依赖不同的 css 样式、公共样式可以单独抽离,这样就形成了不同于过去的 css 文件结构:文件更多、拆分的更细,而同时,在真实的运行环境下,我们却希望文件越少越好,这种情况和 JS 遇到的情况是一致的,因此对于 css 也需要工程化管理;
从另一个角度来说,css 的工程化会遇到更多的挑战,因为 css 不像 JS ,它的语法本身经过这么多年并没有发生多少的变化 (css3 也仅仅是多了一些属性而已),对于 css 语法本身的改变也是一个工程化的课题;
如何解决
这么多年来,官方一直没有提出方案来解决上述问题,一些第三方机构针对不同的问题,提出了自己的解决方案
解决类名冲突
命名约定:即提供一种命名的标准,来解决冲突,常见的标准有:BEM、OOCSS、AMCSS、SMACSS、其他;
css in js:这种方案非常大胆,它觉得 css 语言本身几乎无可救药了,干脆直接用 js 对象来表示样式,然后把样式直接应用到元素的 style 中,这样一来 css 变成了一个一个的对象,就可以完全利用到 js 语言的优势,可以:
- 通过一个函数返回一个样式对象,把公共的样式提取到公共模块中返回;
- 应用 js 的各种特性操作对象,比如:混合、提取、拆分等;
css module:非常有趣和好用的 css 模块化方案,编写简单,绝对不重名;
解决重复样式
css in js:这种方案虽然可以利用 js 语言解决重复样式值的问题,但由于太过激进,很多习惯写 css 的开发者编写起来并不是很适应;
预编译器:有些第三方搞出一套 css 语言的进化版来解决这个问题,它支持变量、函数等高级语法,然后经过编译器将其编译成为正常的 css,常见的预编译器支持的语言有 less、sass 等;
解决 css 文件细分
这一部分要依靠构建工具,例如 webpack 来解决了;
利用一些 loader 或 plugin 来打包、合并、压缩 css 文件;
解决方案
css-in-js
-
用一个 JS 对象来描述样式,而不是 css 样式表,例如下面的对象就是一个用于描述样式的对象:
const styles = { backgroundColor: "#f40", color: "#fff", width: "400px", height: "500px", margin: "0 auto" }
-
由于这种描述样式的方式 根本就不存在类名 ,自然不会有类名冲突,至于如何把样式应用到界面上,不是它所关心的事情,你可以用任何技术、任何框架、任何方式将它应用到界面;
-
css in js 的特点:
- 绝无冲突的可能:由于它根本不存在类名,所以绝不可能出现类名冲突;
- 更加灵活:可以充分利用 JS 语言灵活的特点,用各种招式来处理样式;
- 应用面更广:只要支持 js 语言,就可以支持 css in js ,因此在一些用 JS 语言开发移动端应用的时候非常好用,因为移动端应用很有可能并不支持 css;
- 书写不便:书写样式,特别是公共样式的时候,处理起来不是很方便;
- 在页面中增加了大量冗余内容:在页面中处理 css in js 时,往往是将样式加入到元素的 style 属性中,会大量增加元素的内联样式,并且可能会有大量重复,不易阅读最终的页面代码;
利用 webpack 拆分 css
css 模块化
webpack 常用扩展⚙️ 开发体验问题
上一篇