提到css预编译器(css preprocessor),你可能想到SassLess以及Stylus。而本文要介绍的PostCSS,正是一个这样的工具:css预编译器可以做到的事,它同样可以做到。

“你说的我都懂,那为什么要用它?”

套装与单件

如果Sass等预编译器是新定义了一种模板语言,然后将其转化为css的话,PostCSS则是更纯粹地对css本身做转换。

回想一下你是如何学习使用css预编译器的:了解到有这样一种可以转化为css的语言,它有很多特性,变量、嵌套、继承等等,每一种特性都通过一定语法实现。大概就像是递给你一个已经封装好的工具箱(量产型?),你可以在里面找有用的东西。

那PostCSS是怎样呢?PostCSS就像只递给你一个盒子,但告诉你你可以从旁边的陈列柜取走自己想要的工具放进盒子打包带走。如果你觉得陈列柜里的不够好,PostCSS还可以帮你打造你自己的工具。所以,使用PostCSS,你可以仅取所需。

这就是PostCSS的模块化(modular)风格。它作为一个css转换工具,自身很小,其所有的转换功能都是插件,因此可以个性化配置。

PostCSS的简要原理

PostCSS自身只包括css分析器,css节点树API,source map生成器以及css节点树拼接器。

css的组成单元是一条一条的样式规则(rule),每一条样式规则又包含一个或多个属性&值的定义。所以,PostCSS的执行过程是,先css分析器读取css字符内容,得到一个完整的节点树,接下来,对该节点树进行一系列转换操作(基于节点树API的插件),最后,由css节点树拼接器将转换后的节点树重新组成css字符。期间可生成source map表明转换前后的字符对应关系:

比较有意思的是,PostCSS的插件其实都是JavaScript函数,它们使用PostCSS的节点树API,对css节点树进行不同的转换。

插件预览

所有插件都可以在PostCSS的主页中查询到,这里只选取一小部分示意一下。

Autoprefixer

PostCSS最有名的插件是Autoprefixer。如名所示,可以自动为你添加浏览器私有前缀。它的添加值会参考Can I Use及你设定的浏览器支持范围,因此相当可靠。下面是一个示例(以我设定的浏览器支持范围):

.container{
display: flex;
}

编译后:

.container{
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}

postcss-nested&postcss-mixins

在刚开始使用PostCSS时,我就想到要用PostCSS实现我在Sass中最常用的特性。所以,我找到了postcss-nestedpostcss-mixins。将它们结合起来后,就可以做到这样:

@define-mixin clearfix{
&:after{
display: table;
clear: both;
content: " ";
}
} .column-container{
color: #333;
@mixin clearfix;
}

编译后:

.column-container{
color: #333;
} .column-container:after{
display: table;
clear: both;
content: " ";
}

到这里,你是否已经有了“预编译器可以做到的它也可以做到”的感觉呢?

如何使用PostCSS

我个人推荐结合Gulp使用,本文在此只介绍gulp-postcss的用法。

gulp-postcss及插件都是npm,首先,使用npm install将它们分别安装到项目目录中(会位于node_modules)。然后,编辑glupfile.js,将PostCSS注册为Gulp的一个任务。以下是一个结合使用了Autoprefixerpostcss-simple-varspostcss-mixinspostcss-nested4个插件,且生成source map文件的例子:

var gulp = require("gulp");
var postcss = require("gulp-postcss");
var autoprefixer = require('autoprefixer-core');
var postcssSimpleVars = require("postcss-simple-vars");
var postcssMixins = require("postcss-mixins");
var postcssNested = require("postcss-nested");
var sourcemaps = require("gulp-sourcemaps"); // Css process.
gulp.task("postcss", function(){
var processors = [
postcssMixins,
postcssSimpleVars,
postcssNested,
autoprefixer({
browsers: ["Android 4.1", "iOS 7.1", "Chrome > 31", "ff > 31", "ie >= 10"]
})]; return gulp.src(["./stylesheets/src/*.css"])
.pipe(sourcemaps.init())
.pipe(postcss(processors))
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("./stylesheets/dest"));
});

在上面这段代码中,processors是一个数组,定义了用到的PostCSS插件。PostCSS会按照定义顺序依次执行插件,因此,在结合多个插件使用时,请注意它们的位置。

自定义转换

此外,你可以很容易地创建你自己的转换(还记得前面说过PostCSS的插件都是JavaScript函数吧?)。例如,下面是一个自定义的转换方法,它将css代码中的带有rem单位的值,更改为px的值。

var custom = function(css, opts){
css.eachDecl(function(decl){
decl.value = decl.value.replace(/\d+rem/, function(str){
return 16 * parseFloat(str) + "px";
});
});
};

然后,你将这个方法直接添加到processors中(就像postcssMixins那些那样)就可以使用。如果原来有值是3rem,将变成48px

以上只是一个简单的转换,如果要正式做一个插件,请参考PostCSS插件指南

性能

PostCSS宣称,由JavaScript编写的PostCSS比C++编写的libsass(Sass原本是Ruby编写的,但后来出了C++的引擎,也就是libsass,它更快)还要快3倍。这里的具体数字我觉得不用多关心,可以感受到“PostCSS的运行速度很快”就足够了。

实际运行起来大概这样:

做到更多

基于PostCSS,可以做到许多现有的css预编译器做不到的事。例如,插件系列cssnext可以让你使用CSS4+的语法(增加了变量等许多特性),它会帮你转化为目前可用的CSS3。

一点问题

PostCSS有一个问题,那就是它是零散的,所以我无法找到一个编辑器能正确地解析并高亮准备使用PostCSS的css代码。例如在WebStorm中我把它当做普通的css文件,结果就会收到很多红色的错误提示。

所以,css预编译器过时了吗?

当然不会。就像其他流行的框架和工具那样,css预编译器是已经验证过的可用工具,我们完全可以根据需要选用。

Sass等css预编译器的特点是成熟可靠。一方面,它们已经是流行的模板语言,有完善的文档和周边支持,相对稳定,新加入团队的人也能比较容易地理解。另一方面,集成的风格有它的方便之处,就像你可能会懒得去组装一个模型,但能找到专业的人替你完成。

PostCSS的特点则是模块化。从长远来看,PostCSS可以做到更多类型的css转换。而可定制的风格非常适合追求个性的人(更快捷,而且可以自己做出很有趣的插件)。

此外,css预编译器和PostCSS可以协同使用。有一个流行的用法就是Sass编译后再接PostCSS的Autoprefixer(毕竟这是PostCSS的招牌插件)。

结语

PostCSS的风格可以说是在打造一个改变css开发方式的生态系统。所以如果说到未来,还是挺期待的。

(重新编辑自我的博客,原文地址:http://acgtofe.com/posts/2015/05/modular-transforming-with-postcss/

在 CSS 预编译器之后:PostCSS的更多相关文章

  1. CSS预编译与PostCSS以及Webpack构建CSS综合方案

    CSS全称Cascading Style Sheets(层叠样式表),用来为HTML添加样式,本质上是一种标记类语言.CSS前期发展非常迅速,1994年哈肯·维姆·莱首次提出CSS,1996年12月W ...

  2. CSS预编译器

    零.CSS预编译器 CSS预处理器是指对生成CSS前的某一语法的处理.CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,供项目使用 CSS预处理器为CSS增加一 ...

  3. CSS预编译器配置-------LESS Sass Stylus webstorm

    预编译器配置说明 开头语,发挥CSS预处器的作用是一种很有挑战性的事情.CSS预处器有不同的语言,就有不同的语法和功能. 语法 在使用CSS预处器之前最重要的是对语法的理解,幸运的是,这三种CSS预处 ...

  4. css预编译器——Less的使用

      方法一:仅介绍在客户端环境下使用的方法 1 新建test.less并引入.less该文件(和css一样在head处引入),注意rel="stylesheet/less": &l ...

  5. CSS预编译器:Sass(入门),更快的前端开发

    SASs是由美国注册会计师协会(AICPA)下属审计准则委员会(ASB)发布,是为了便于注册会计师执行和落实一般公认审计准则(GAAS). Sass 扩展了 CSS3,增加了规则.变量.混入.选择器. ...

  6. CSS预编译器less简单用法

    1.变量 定义变量 @变量名:值; @test_width:100px; 使用变量 .box{ width:@test_width; height:@test_width; background-co ...

  7. CSS预编译器:Sass(进阶),更快的前端开发

    1.@if     @if 指令是一个 SassScript,它可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块 在 Sass 中除了 @if 之,还 ...

  8. stylus(css预编译器)

    推荐去张鑫旭大神这里详细了解:http://www.zhangxinxu.com/jq/stylus/ 安装 npm install -g stylus 自动编译 $ stylus -w demo.s ...

  9. 前端学习笔记系列一:6 一种新的css预编译器stylus

    stylus是 CSS 的预处理框架.CSS 预处理,顾名思义,预先处理 CSS.那 stylus 咋预先处理呢?stylus 给 CSS 添加了可编程的特性,也就是说,在 stylus 中可以使用变 ...

随机推荐

  1. Linux 内核概述 - Linux Kernel

    Linux 内核学习笔记整理. Unix unix 已有40历史,但计算机科学家仍认为其是现存操作系统中最大和最优秀的系统,它已成为一种传奇的存在,历经时间的考验却依然声名不坠. 1973 年,在用 ...

  2. CRC、反码求和校验 原理分析

    3月份开始从客户端转后台,算是幸运的进入全栈工程师的修炼阶段.这段时间一边是老项目的客户端加服务器两边的维护和交接,一边是新项目加加加班赶工,期间最长经历了连续工作三天只睡了四五个小时的煎熬,人生也算 ...

  3. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  4. android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

    目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...

  5. .NET应用程序域

    在.NET平台下,可执行程序并没有直接承载在Windows进程中,而非托管程序是直接承载的..NET可执行程序承载在进程的一个逻辑分区中,称之为应用程序域(AppDomain).一个进程可以包含多个应 ...

  6. VS2015在创建项目时的一些注意事项

    一.下面是在创建一个新的项目是我最常用的,现在对他们一一做一个详细的介绍: 1.Win32控制台应用程序我平时编写小的C/C++程序都用它,它应该是用的最多的. 2.名称和解决方案名称的区别:名称是项 ...

  7. java中易错点(一)

    由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/".如果想替换的只是&qu ...

  8. Express 教程 01 - 入门教程之经典的Hello World

    目录: 前言 一.Express?纳尼?! 二.开始前的准备工作 三.测试安装之经典的Hello World 四.使用express(1)来生成一个应用程序 五.说明 前言: 本篇文章是建立在Node ...

  9. MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记

    MonoDevelop 4.2.2/Mono 3.4.0 in CentOS 6.5 安装笔记 说明 以root账户登录Linux操作系统,注意:本文中的所有命令行前面的 #> 表示命令行提示符 ...

  10. Mono+Jexus部署C# MVC的各种坑

    如果你看到这篇文章,先别急着动手,过完一遍,确定是你要的再动手. 别人提到的这里不赘述,只说查了好久才知道的. 1号坑:System.IO.FileNotFoundException Could no ...