PostCSS 究竟是个什么鬼?

如果你还没有使用过 PostCSS,那么从现在开始,找个项目尝试一下,给 PostCSS 一个机会,你会发现,她几乎可以完成你所有和 CSS 相关的工作(包括 Sass 和 Less 这些预处理器的工作),极大的提高你处理 CSS 的效率。

用过 PostCSS 的同学可能会存在些疑问:这货和日常用的 CSS 预处理器有什么区别,有什么优势?CSS 后处理器又是个什么东西... ...?OK,下面的内容希望可以解开你心中的疑问。

以下内容摘自 PostCSS Deep Dive: What You Need to Know,根据我个人的理解,翻译整理。

一句话解释 PostCSS 是什么

下面的定义翻译自 PostCSS 的项目主页:

PostCSS 是一个使用 JS 插件来转换 CSS 的工具。这些插件可以支持使用变量,混入(mixin),转换未来的 CSS 语法,内联图片等操作。

简而言之,PostCSS 可以将 CSS 转变成 JavaScript 可以操作的数据格式。基于 JS 写的插件可以完成上面所说的那些操作。PostCSS 本身不会对 CSS 代码作任何修改,她只是为插件提供了一些接口,方便插件完成它们各自的功能。

理论上讲,PostCSS 的插件可以对 CSS 实现各种操作,没有任何限制。只要你能想得到,你就可以写一个插件来实现你的想法。

PostCSS 的插件可以实现预处理器的功能;它们还可以优化并且自动给代码添加各种前缀;它们可以添加未来语法的支持,还可以提示代码检查的功能,它们可以处理变量和代码逻辑,可以提供完整的网格系统;还可以提供代码缩写... ... 等各种各样的操作。

PostCSS 不是什么

一方面,你可以使用 PostCSS 的插件来完成各种操作,另一方面,PostCSS 以相对来说比较年轻,这导致了一些人对这个工具到底是什么产生了一些误解。

所以,在深入讨论之前,让我们先弄清楚 PostCSS 不是什么。

PostCSS 不是预处理器

许多开发者已经表示由于 PostCSS 的原因,他们将不再倾向于使用预处理器。与此同时,也有一些开发者表示他们更倾向于使用当前的预处理器,对 PostCSS 无爱。但是,PostCSS 并不是预处理器。

没错,如果你愿意的话,你当然可以把她当成预处理器来使用,但是,你可以用她来实现一些非预处理的功能。你甚至还可以将她和你喜欢的预处理器结合起来使用。

PostCSS 不是后处理器(post-processor)

尽管 PostCSS 这个名字中包含一个 "post",但是,她也算不上是一个真正的后处理器。典型的后处理操作是将符合 CSS 语法标准的样式文件作为输入,然后对其进行处理,如添加浏览器前缀等。但是,PostCSS 并不仅限于完成这些功能。如我们上面提到的那样,她也可以被当成预处理器来使用。

也许,最好的方式就是把她当成「处理器」,就像 PostCSS 的作者 Andrey Sitnik 在 Twitter 上说的那样。

It is time admit my mistakes. “Postprocessor” term was bad. PostCSS team stoped to use it. https://t.co/vs2AiXGoJy

— PostCSS (@PostCSS) July 28, 2015

还有,像作为 PostCSS 多产的贡献者之一及插件开发者的 Maxime Thirouin 在 Twitter 所说的那样,我们最好把 PostCSS 中的 "post" 想像成「更强大的 CSS」(CSS and beyond),而不是 "post"-processing 中的 "post"。

@HugoGiraudel nobody in postcss contributors is using this expression anymore. Now it is Postcss like "css and beyond"

— Maxime Thirouin (@MoOx) July 21, 2015

PostCSS 不是「未来的语法」

PostCSS 有很多优秀的且广为人知的插件使得你可以用未来的 CSS 语法,例如,使用那些在将来可以使用,但在现阶段支持情况还不理想的语法。然而,PostCSS 并不是专门设计用来写未来的 CSS 的。

一些开发者表示,他们并不太情愿使用 PostCSS,原因是他们太习惯于使用未来的语法。然而,使用未来的语法只是 PostCSS 众多功能中的一个。

PostCSS 不是一个清理/优化工具

Autoprefixer 这个插件的成功,使得很多人把 PostCSS 当成是一个用来清理和优化你已经完成的 CSS 代码的工具。我之前也一度是这样认为的,直到有一天,我了解了使用 PostCSS 还可以完成很多其他的工作。

诚然,PostCSS 有很多非常棒的插件提供了清理和优化的功能,但是,这些只是 PostCSS 所提供的一部分。

PostCSS 不是单一的东西

需要强调的一点是,PostCSS 不是局限于某一类型的功能;她代表着一系列的高度定制化、配置化的功能的集合,她的潜力是无限的。

作为类比,我们可以考虑一下 WordPress。她的电子商务相关的插件非常的受欢迎,但是没有人会把 WordPress 当成是一个电商引擎,而且,WordPress 的价值也不是依据这些电商插件来估计的。

什么造就了 PostCSS

PostCSS 是一个完全不同于 CSS 的东西。用一位前端开发者的话说就是『她是 CSS 开发中的瑞士军刀』,这种描述非常的恰当。

接下来,我们来具体看一下究竟是什么造就了 PostCSS。

插件生态圈提供了各种各样的功能

她的长长的插件列表使得她显得格外的引人注意。当你在她的 GitHub 页面中浏览插件时,你会发现,这是第一次这么多的功能集中展示在一个地方。

有些插件可以让你使用未来的语法,允许你使用诸如颜色函数,径向渐变,自定义属性,自定义选择器,为媒体查询自定义别名以及许多其他的功能。

有些降级的插件用来创建一些旧式的说法,例如,为 rgba() 这个颜色函数添加十六进制的降级表示方法,为 IE8 添加不透明滤镜,为 IE8 转换伪元素选择器,为 rem 单位生成 px 的降级表示方式。

有超过二十个语言扩展的插件,包括添加混入(mixin),变量,条件判断,for 和 each 的循环,BEM 和 SUIT 风格的命名方式等等。

还有一些颜色管理的插件,用来把颜色从一种格式转换到另一种格式,修改颜色的 alpha 透明度,合成颜色等。

模块化,用你所需

PostCSS 插件化的另一方面的好处是,你可以根据自己的需要或多或少的选择相应的插件。

你想让你的 CSS 代码的性能和浏览器兼容性更好吗?使用几个优化的插件就可以满足你的需求。

想把 PostCSS 变成一个预处理器吗?使用几个语言扩展的插件就可以满足你的需求。

例如,你可以选择一些语言扩展插件,来创建你自己的预处理器。或者,你可以使用 PreCSS 这个插件包,有了这个插件包,你可以一次性使用多个语言扩展的功能。

无论你想用哪种方式使用 PostCSS,你都可以根据你自己的需求选择所需的插件,这意味着你不用使用那些没有用到的功能。

速度快:高达 3 倍之多

PostCSS 之所以会这么快有两个主要原因。一个原因是你只需要加载你所需要的插件,正如上面提到的那样。另一个原因是,她是用 JavaScript 写的。

你可以通过下面的链接来自己运行一下基准测试:
https://github.com/postcss/benchmark

下面是测试的结果,包括解析,规则嵌套,混入(mixin),变量和数学计算。

PostCSS:   36 ms  
Rework:    77 ms   (2.1 times slower)  
libsass:   136 ms  (3.8 times slower)  
Less:      160 ms  (4.4 times slower)  
Stylus:    167 ms  (4.6 times slower)  
Stylecow:  208 ms  (5.7 times slower)  
Ruby Sass: 1084 ms (30.1 times slower)  

任何想法都可以写成插件

PostCSS 的插件是用 JavaScript 写的,只要你有想法,有一定的 JS 基础,你就可以把你的想法用插件的形式实现出来。和原文中的作者一样,我也在闲暇时间写了一个插件 —— postcss-urlrev 用来为 CSS 中引用的静态资源添加 md5 时间戳。

你可以使用常规的 CSS

有很大一部分插件是不需要像预处理器那样使用自定义的语法的。相反,你可以使用常规的 CSS。这意味着你可以在任何现有的项目中使用 PostCSS。

这同样意味着你不会被任何预处理器所限制,因为 PostCSS 处理的就是普通的 CSS 文件。例如,如果一个项目中使用了 Sass,并且你想对它做优化操作,那你就必须先用 Sass 编译成普通的 CSS 文件再进行处理。

PostCSS 的库没有和任何预处理器绑定

具体说来,在一个公共的 CSS 项目中,如果使用了预处理器,你可能需要维护 Sass 版,Less 版等。但是如果使用 PostCSS 的话你就可以只维护一个版本了,因为她本身也提供了预处理器的功能。

和构建工具无缝集成

PostCSS 本身就是由 JavaScript 写成的,你不需要安装 Ruby 环境。像 Grunt,Gulp,webpack 等这些流行的构建工具都有对应的插件,上手非常容易。