资讯专栏INFORMATION COLUMN

在 CSS 预编译器之后:PostCSS

NeverSayNever / 563人阅读

摘要:提到预编译器,你可能想到以及。而本文要介绍的,正是一个这样的工具预编译器可以做到的事,它同样可以做到。所以,预编译器过时了吗当然不会。等预编译器的特点是成熟可靠。此外,预编译器和可以协同使用。

提到css预编译器(css preprocessor),你可能想到Sass[]以及[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[]及你设定的浏览器支持范围,因此相当可靠。下面是一个示例(以我设定的浏览器支持范围):

.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及插件都是[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)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/111070.html

相关文章

  • 更便捷的css处理方式-PostCSS

    摘要:本身并不直接用于处理样式,只有配合它的插件,才能完成相关的编译工作。是很容易引入当前的工作流中的。无论是还是,都有比较方便的方式。 一般来说介绍一个东西都是要从是什么,怎么用的顺序来讲。我感觉这样很容易让大家失去兴趣,先看一下postcss能做点什么,有兴趣的话再往下看,否则可能没有耐心看下去。让我们开始吧 postcss能做什么 补全css属性浏览器前缀 手写的代码可以是这样的: ....

    AlexTuan 评论0 收藏0
  • 深入wepy源码:wpy文件编译过程

    摘要:深入源码文件编译过程是腾讯开源的一款小程序框架,主要通过预编译的手段,让开发者采用类风格开发。处理好的最终会写入文件中,文件存储路径会判断类型是否为。根据上面的流程图,可以看出所有的文件生成之前都会经过处理。 深入wepy源码:wpy文件编译过程 wepy 是腾讯开源的一款小程序框架,主要通过预编译的手段,让开发者采用类 Vue 风格开发。 让我们一起看看, wepy 是如何实现预编译...

    stdying 评论0 收藏0
  • 【30分钟】吃透webpack,也许这一篇就够了

    摘要:否则可能会导致全局安装的版本与项目中的配置文件可能存在不匹配。是一个流行的插件,其作用是为中的属性添加浏览器特定的前缀。插件允许开发人员在当前的项目中使用将来版本中可能会加入的新特性。 本文webpack是在Mac平台下基于官方最新版本v3.10,对于webpack@v2会有小的差异,待全文完成后会补充webpack@v2与v3版本之间的差异 使用webpack前的准备 1、初始化一个...

    KitorinZero 评论0 收藏0
  • 谈谈PostCSS

    摘要:它们有个统一的名字预处理器。面对以上问题,预处理器给出了非常可行的解决方案变量就像其他编程语言一样,免于多处修改。回到话题中,之所以会出现向预处理器这样子的解决方案,归根结底还是标准发展的滞后性导致的。 前言 现在的前端,javascript的发展有目共睹,框架林立。同时,html也是齐头并进,推出了HTML5标准,并且得到了普及。这样的发展却唯独少了一个角色? CSS,就是这个看似不...

    高胜山 评论0 收藏0
  • 谈谈PostCSS

    摘要:它们有个统一的名字预处理器。面对以上问题,预处理器给出了非常可行的解决方案变量就像其他编程语言一样,免于多处修改。回到话题中,之所以会出现向预处理器这样子的解决方案,归根结底还是标准发展的滞后性导致的。 前言 现在的前端,javascript的发展有目共睹,框架林立。同时,html也是齐头并进,推出了HTML5标准,并且得到了普及。这样的发展却唯独少了一个角色? CSS,就是这个看似不...

    leap_frog 评论0 收藏0

发表评论

0条评论

NeverSayNever

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<