CSS

postcss 是什么

按官网 https://postcss.org/ 上的介绍,它是一个 用 JavaScript 转换 CSS 的工具(A tool for transforming CSS with JavaScript) 。
与之类似的有 Sass 、Less 跟 Stylus 等 CSS 预处理器 ,可以通过更简便的方法去写 CSS 。
虽然利用 postcss 也可以写出变量 、函数、混合宏、扩展、条件语句、循环等 CSS 不支持(或者支持度)不高的语法,但是 postcss 本质还是一个 与业务无关的CSS工具 ,而实现以上诸多功能的还是依赖于社区上的各种插件 。
它的作用就如同 JS 里的 babel 一般。

postcss 可以做什么

增强代码的可读性

利用从 Can I Use 网站获取的数据为 CSS 规则添加特定厂商的前缀。Autoprefixer 自动获取浏览器的流行度和能够支持的属性,并根据这些数据自动为 CSS 规则添加前缀。
示例如下:

  1. // 输入
  2. :fullscreen {
  3. }
  4. // 输出
  5. :-webkit-full-screen {
  6. }
  7. :-ms-fullscreen {
  8. }
  9. :fullscreen {
  10. }

将未来的 CSS 特性带到今天!

PostCSS Preset Env 将最新的 CSS 语法转换成大多数浏览器都能理解的语法,并根据目标浏览器或运行时环境来确定需要的 polyfills,此功能基于 cssdb 实现。
示例如下:

  1. // 输入
  2. body {
  3. color: lch(53 105 40);
  4. }
  5. // 输出
  6. body {
  7. color: rgb(250, 0, 4);
  8. }

终结全局 CSS

CSS 模块 永远不用担心命名太大众化而造成冲突,只要用最有意义的名字就行了。
示例如下:

  1. // 输入
  2. .name {
  3. color: gray;
  4. }
  5. // 输出
  6. .Logo__name__SVK0g {
  7. color: gray;
  8. }

避免 CSS 代码中的错误

通过使用 stylelint 强化一致性约束并避免样式表中的错误。stylelint 是一个现代化 CSS 代码检查工具。它支持最新的 CSS 语法,也包括类似 CSS 的语法,例如 SCSS 。
示例如下:

  1. // 输入
  2. a {
  3. color: #d3;
  4. }
  5. // 控制台输出
  6. app.css
  7. 2:10 Invalid hex color

postcss 怎么用

可以以 webpack 为例看看如何进行配置。
首先就是安装基础插件:

  1. npm install postcss-loader postcss --save-dev
  2. or
  3. yarn add postcss-loader postcss -D

然后在 webpack.config.js 里添加:

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.css$/,
  6. use: ['style-loader', 'css-loader', 'postcss-loader'],
  7. },
  8. ],
  9. }
  10. }

然后在根目录下创建文件 postcss.config.js ,内容如下:

  1. module.exports = {
  2. plugins: [],
  3. }

现在就为在 postcss可以做什么 里提到的4个特性来添加相应的插件。
4个特性对应的插件如下:

autoprefixer(增强代码的可读性)

安装方式:

  1. npm install autoprefixer --save-dev
  2. or
  3. yarn add autoprefixer -D

配置如下:

  1. // postcss.config.js
  2. const autoprefixer = require('autoprefixer')
  3. module.exports = {
  4. plugins: [
  5. autoprefixer
  6. ],
  7. }

autoprefixer 是与 browserslist 进行关联, browserslist 就是一个告知打包工具项目将会运行的浏览器以及node平台,以此来创建相应的兼容性代码的工具。
所以可以在 package.json 里添加 browserslist 属性,或者在根目录添加 .browserslistrc 文件,示例如下(具体规则可根据项目情况来进行配置):

  1. last 2 version
  2. > 1%
  3. IE 11

browserslist 的数据都是来自 https://caniuse.com/ 的。
可以通过 https://browserslist.dev 来查看语句匹配情况。截图如下:
使用 Postcss增强 CSS 代码 - 图1
所以有:

  1. // input
  2. .example {
  3. display: grid;
  4. transition: all .5s;
  5. user-select: none;
  6. background: linear-gradient(to bottom, white, black);
  7. }
  8. // output
  9. /*
  10. * Prefixed by https://autoprefixer.github.io
  11. * PostCSS: v7.0.29,
  12. * Autoprefixer: v9.7.6
  13. * Browsers: last 2 version
  14. */
  15. .example {
  16. display: -ms-grid;
  17. display: grid;
  18. -webkit-transition: all .5s;
  19. transition: all .5s;
  20. -webkit-user-select: none;
  21. -moz-user-select: none;
  22. -ms-user-select: none;
  23. user-select: none;
  24. background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
  25. background: linear-gradient(to bottom, white, black);
  26. }

可以通过 https://autoprefixer.github.io/ 在线看编译效果

postcss-preset-env(将未来的 CSS 特性带到今天!)

安装方式:

  1. npm install postcss-preset-env --save-dev
  2. or
  3. yarn add postcss-preset-env -D

配置如下:

  1. // postcss.config.js
  2. const postcssPresetEnv = require('postcss-preset-env')
  3. module.exports = {
  4. plugins: [
  5. postcssPresetEnv(/* pluginOptions */)
  6. ],
  7. }

postcss-preset-env 可以用一些浏览器支持率不高或者尚未支持的 CSS属性 。
示例如下:

  1. // input
  2. :root {
  3. --fontSize: 1rem;
  4. --mainColor: #12345678;
  5. --secondaryColor: lab(32.5 38.5 -47.6 / 90%);
  6. }
  7. @custom-media --viewport-medium (width <= 50rem);
  8. @media (--viewport-medium) {
  9. body {
  10. color: var(--mainColor);
  11. font-family: system-ui;
  12. font-size: var(--fontSize);
  13. line-height: calc(var(--fontSize) * 1.5);
  14. overflow-wrap: break-word;
  15. padding-inline: calc(var(--fontSize) / 2 + 1px);
  16. }
  17. }
  18. // output Stage 0 > 3%
  19. :root {
  20. --fontSize: 1rem;
  21. --mainColor: rgba(18,52,86,0.47059);
  22. --secondaryColor: rgba(102, 51, 153, 0.9);
  23. }
  24. @media (max-width: 50rem) {
  25. body {
  26. color: var(--mainColor);
  27. font-family: system-ui;
  28. font-size: var(--fontSize);
  29. line-height: calc(var(--fontSize) * 1.5);
  30. overflow-wrap: break-word;
  31. padding-left: calc(var(--fontSize) / 2 + 1px);
  32. padding-right: calc(var(--fontSize) / 2 + 1px);
  33. }
  34. }

可以通过 https://csstools.github.io/postcss-preset-env/ 在线看编译效果。
它可选的选项有7个,分别是:stagefeaturesbrowsersinsertBeforeinsertAfterautoprefixerpreserveimportFrom
具体选项说明与示例可参考 https://github.com/csstools/postcss-preset-env
这里要着重分享两个选项:

stage

在谈 stage 这个选项之前,首先得先知道一个概念—— cssdb 。
cssdb 是 postcss-preset-env 的实现基准,主要就是 CSS 的新功能功能及这些功能从提出到成为标准时所在的进程。
cssdb 跟 ecma 一样,对新属性分了不同的进程,具体的进程如下:
Stage 0:脑袋风暴阶段。高度不稳定,可能会发生变化。
Stage 1:实验阶段。也非常不稳定,可能会发生变化,但是该提案已得到W3C成员的认可。
Stage 2:承认阶段。高度不稳定并且可能会发生变化,但是正在积极研究中。
Stage3:拥抱阶段。稳定且变化不大,此功能可能会成为标准。
Stage4:标准阶段。最终的解决方案,所有主流浏览器都支持。
所以 stage 这个配置的可选项就是 1、2、3、4 了。

features

features 选项按 ID 启用或禁用特定的 polyfill 。启用就是 true 。
具体可参考 https://github.com/csstools/postcss-preset-env/blob/master/src/lib/plugins-by-id.js#L36

css-modules(终结全局 CSS)

安装方式:

  1. npm install postcss-modules --save-dev
  2. or
  3. yarn add postcss-modules -D

配置如下:

  1. // postcss.config.js
  2. const postcssModules = require('postcss-modules')
  3. module.exports = {
  4. plugins: [
  5. postcssModules(/* pluginOptions */)
  6. ],
  7. }

css-modules 支持以模块化的形式来编写代码。示例如下:

  1. // input
  2. .grid {
  3. display: grid;
  4. grid: repeat(2, 240px) / auto-flow 320px;
  5. & > div {
  6. background-color: #8ca0ff;
  7. width: 200px;
  8. height: 200px;
  9. transition: 1s;
  10. }
  11. }
  12. // output
  13. .demo__grid___2lKm5 {
  14. display: -ms-grid;
  15. display: grid;
  16. grid: repeat(2,32vw) / auto-flow 42.667vw
  17. }
  18. .demo__grid___2lKm5 > div{
  19. background-color: #8ca0ff;
  20. width: 26.667vw;
  21. height: 26.667vw;
  22. -webkit-transition: 1s;
  23. transition: 1s
  24. }

其实在这里,如果不使用 postcss-modules ,也可以直接利用 css-loader 开启 css 模块化,具体配置如下:

  1. // webpack.config.js
  2. module.exports = {
  3. module: {
  4. rules: [
  5. {
  6. test: /\.css$/i,
  7. use: [
  8. {
  9. loader: "css-loader",
  10. options: {
  11. modules: true,
  12. importLoaders: true,
  13. localIdentName: '[name]__[local]___[hash:base64:5]'
  14. }
  15. },
  16. ],
  17. },
  18. ],
  19. },
  20. }

stylelint(避免 CSS 代码中的错误)

如果在 JS 中可以使用 eslint 进行代码检查一样,在 CSS 中也可以通过 stylelint 来进行代码检查。
安装方法:

  1. npm install stylelint stylelint-config-standard --save-dev
  2. or
  3. yarn add stylelint stylelint-config-standard -D

配置如下:

  1. // webpack.config.js
  2. const StyleLintPlugin = require('stylelint-webpack-plugin')
  3. module.exports = {
  4. plugins: [
  5. new StyleLintPlugin(/* pluginOptions */)
  6. ]
  7. }

然后在根目录上创建 .stylelintrc 或者 stylelint.config.js 文件(具体文件可在 StyleLintPlugin 中配置),其内容如下:

  1. {
  2. "extends": "stylelint-config-standard",
  3. "rules": {/* pluginOptions */}
  4. }

所以当代码不规范时,就可以在命令行里看到类似的报错:
也可以在 编辑器 里找到对应的 stylelint 插件,从而进行CSS代码自动格式化。

ying-template

ying-template (https://github.com/KRISACHAN/ying-template) 是鱼头在 GitHub 上开源的一个基于 webpack5 + typeScript4 + postcss8 的一个多页面脚手架,在最开始的版本中也引入了 sass、less ,不过后来因为 postcss 太香,就直接去除了 sass、less ,只留下 postcss 。
ying-template 目前已经在鱼头老东家的一个专利项目中投入了生产,而鱼头另一个开源库 ying-datastructures-algorithms (https://github.com/KRISACHAN/ying-datastructures-algorithms) (一个算法与数据结构 typescript 描述库)也在使用中,另外社区中也有一些小伙伴在项目中使用或借鉴了,各位有兴趣也可以 clone 下来看一下,可以感受下在 postcss 下的 css 是多么有魅力。
另外值得一提的是,除了上面介绍的几个基础插件之外,postcss 社区上也有许多有意思的插件,各位可以通过 https://www.postcss.parts/ 来选择自己所需要的插件进行使用。