[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)
- 必备基础
- 基础知识
- BFC
- 层叠上下文 Stacking Context
- 视觉格式化模型 Visual formatting model
- CSS3中使用HSL颜色指南
- z-index
- line-height
- vertical-align 属性
- 垂直居中
- overflow
- CSS3 Gradients
- CSS3 动画基础
- 难点知识
- 布局篇
- Flex布局
- =====
- Grid布局
- 多列布局
- 高级布局
- 预编译器篇
- PostCSS
- Sass
- stylus
- 模块篇
- 良好的使用
- CSS 模块化
- 技巧篇
- 未来的CSS
- 动画篇
- 工具篇
- CSS架构
- CSS 命名方法论
- BEM
- CSS解释器
- 常用框架
- 参考
- 唰唰声