合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
[TOC] # 简介 从原生的 Css 到 CSS Modules,再到 Css In Js,目标是让开发者更高效地写组件的样式。Styled Components 是基于 Css In Js 方式实现的一个库。目前主要服务于React。 # Styled-components 官网:https://www.styled-components.com/ 说一下 css-in-js,这玩意不是让我们退化到写内连样式,而是使用 styled-components 1. 首先,styled-components 所有语法都是标准 css 语法,同时支持 scss 嵌套等常用语法,覆盖了所有 css 场景。 2. 在样式复写场景下,styled-components 支持在任何地方注入全局 css,就像写普通 css 一样 3. styled-components 支持自定义 className,两种方式,一种是用 babel 插件:https://github.com/styled-components/babel-plugin-styled-components, 另一种方式是使用 styled.div.withConfig({ componentId: "prefix-button-container" }) 相当于添加 className="prefix-button-container" 4. className 语义化更轻松,这也是 class 起名的初衷 5. 更适合组件库使用,直接引用 import "module" 即可,否则你有三条路可以走:像 antd 一样,单独引用 css,你需要给 node_modules 添加 css-loader;组件内部直接 import css 文件,如果任何业务项目没有 css-loader 就会报错;组件使用 scss 引用,所有业务项目都要配置一份 scss-loader 给 node_modules;这三种对组件库来说,都没有直接引用来的友好 6. 当你写一套组件库,需要单独发包,又有统一样式的配置文件需求,如果这个配置文件是 js 的,所有组件直接引用,对外完全不用关注。否则,如果是 scss 配置文件,摆在面前还是三条路:每个组件单独引用 scss 文件,需要每个业务项目给 node_modules 添加 scss-loader(如果业务用了 less,还要装一份 scss 是不);或者业务方只要使用了你的组件库,就要在入口文件引用你的 scss 文件,比如你的组件叫 button,scss 可能叫 common-css,别人听都没听过,还要查文档;或者业务方在 webpack 配置中单独引用你的 common-css,这也不科学,如果用了3个组件库,天天改 webpack 配置也很不方便。 7. 当 css 设置了一半样式,另一半真的需要 js 动态传入,你不得不 css + css-in-js 混合使用,项目久了,维护的时候发现某些 css-in-js 不变了,可以固化在 css 里,css 里固定的值又因为新去求变得可变了,你又得拿出来放在 css-in-js 里,实践过就知道有多么烦心。 ----by [黄子毅](https://www.zhihu.com/people/huang-zi-yi-83) # [CSS Modules](https://github.com/css-modules/css-modules) 详解 CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。 产生局部作用域的唯一方法,就是使用一个独一无二的class的名字,不会与其他选择器重名。这就是 CSS Modules 的做法。 Sass/Less/PostCSS 等解决 CSS 编程能力弱的问题,但这**并没有解决模块化最重要的问题**。 CSS 模块化重要的是要解决好两个问题:CSS 样式的导入和导出。 1. 灵活按需导入以便复用代码; 2. 导出时要能够隐藏内部作用域,以免造成全局污染。 CSS 模块化的解决方案有很多,但主要有两类。 1. 一类是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。[Radium](https://github.com/FormidableLabs/radium),[jsxstyle](https://github.com/petehunt/jsxstyle),[react-style](https://github.com/js-next/react-style) 属于这一类。优点是能给 CSS 提供 JS 同样强大的模块化能力;缺点是不能利用成熟的 CSS 预处理器(或后处理器) Sass/Less/PostCSS,`:hover` 和 `:active` 伪类处理起来复杂。 2. **另一类是依旧使用 CSS,但使用 JS 来管理样式依赖,代表是 CSS Modules**。CSS Modules 能最大化地结合现有 CSS 生态和 JS 模块化能力,API 简洁到几乎零学习成本。发布时依旧编译出单独的 JS 和 CSS。 **它并不依赖于 React,只要你使用 Webpack,可以在 Vue/Angular/jQuery 中使用。** 是我认为目前最好的 CSS 模块化解决方案。近期在项目中大量使用,下面具体分享下实践中的细节和想法。 ## 优点 CSS Modules 很容易学,它不是将 CSS 改造成编程语言,而是功能很单纯,**只加入了局部作用域和模块依赖**,同时又非常有用,可以保证某个组件的样式,不会影响到其他组件,这恰恰是网页组件最急需的功能。 ## css-loader和style-loader 那么,css-loader和style-loader是干什么用的呢? 引用《入门webpack》中的原文:css-loader 使你能够使用类似`@import`和`url(...)`的方法实现`require`的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的js文件中。 因此,我们这样配置后,遇到后缀为.css的文件,webpack先用css-loader加载器去解析这个文件,遇到“@import”等语句就将相应样式文件引入(所以如果没有css-loader,就没法解析这类语句),最后计算完的css,将会使用style-loader生成一个内容为最终解析完的css代码的style标签,放到head标签里。 需要注意的是,loader是有顺序的,webpack肯定是先将所有css模块依赖解析完得到计算结果再创建style标签。因此应该把`style-loader`放在`css-loader`的前面(webpack loader的执行顺序是从右到左)。 # 参考 [CSS Modules 用法教程](http://www.ruanyifeng.com/blog/2016/06/css_modules.html) [深度解读CSS工程化实践成果](http://www.uml.org.cn/ajax/201710111.asp?artid=20737) [写CSS的姿势](https://www.w3cplus.com/css/css-evolution.html) [精读《请停止 css-in-js 的行为》](https://zhuanlan.zhihu.com/p/26878157)