记一次postcss分享总结

最近在公司给同事们分享了一下postcss,在这里作一个简单总结:css

在咱们平常写css的过程当中,通常会有哪些以为比较繁琐的地方??
这里我列举我本身平常开发中以为比较繁琐的几点:css3

  • 前缀问题;
  • 有时候为了规范或是精确性咱们会写一些比较深的选择器;
  • 在不肯定一些css属性兼容性的时候,咱们常常须要查询一些属性的浏览器兼容性;

上面提到的问题,postcss中都有相应的插件能够帮咱们解决对应的问题,下面的问题是,postcss是什么?git

在看一些讲postcss的文章里,会说明postcss不是相似sass、less的预处理器,也不是后处理器,那postcss究竟是什么?这时候。。。直接看API:github

clipboard.png

上面列举的是api中一些基本的类说明(详细api移步:http://api.postcss.org/),结合postcss文档中说明的postcss的工做流:web

workflow:

clipboard.png

Core Structor

clipboard.png

总结说明:
postcss处理css的方式,主要区分三部分:npm

  • parser过程:将css字符串解析成可供咱们操做的JavaScript对象
  • processor过程:咱们应用postcss插件、或是自定义插件,都是在这个过程当中,根据postcss提供的API,对parser生成的js对象作相应调整;
  • stringfier过程:将咱们处理后的js对象,再转换回为css字符串

下面经过具体的代码说明一下postcss 对css的转换:
npm 安装postcss、代码以下:json

var postcss = require('postcss')
var root    = postcss.parse('a{color:white;} b{width:100px}')

返回的root对象的内容为下图:gulp

clipboard.png

由上图能够看到,root对象是咱们css代码结构化生成的js对象,里边对应包含咱们的选择器、css属性名、属性值等等(图中标示了一些很容易理解的信息,想要了解详细能够移至官方api:http://api.postcss.org/),通过这一步以后,咱们能够操做这个js对象,作出一切咱们想要的改变,而后再由stringfile转换为最终的css代码。小程序

有了上面这些,在使用postcss的时候,就有了一些基本的认知。下面介绍几款经常使用的插件:api

插件

Autoprefixer:

这应该是postcss最广为人知的一个插件了 ,这个插件能够:

  • 能够指定浏览器版本、范围

    • 在插件参数中指定
    • use .browserslistrc config
    • package.json with browserslist key
  • 去除过期的前缀

precss

这款插件相似less、sass ,可让咱们在css中使用变量、css嵌套、函数、mixin
除了precss,还有不少细粒度的插件,好比:

  • postcss-nested:专门支持css嵌套写法:
  • postcss-define-function :实现相似sass 函数功能
  • postcss-for:专门增长循环支持
  • ...

doiuse:

能够为咱们检查浏览器支持

cssnano:

css压缩(会进行一些合并转换操做 ,示例会说明)

详细插件列表及分类,请移至:https://github.com/postcss/po...

代码示例:
说明:示例基于gulp+gulp-postcss
npm安装好gulp、gulp-postcss以及对应的插件,下面的实例使用到postcss-nested、cssnano、postcss-apply、autoprefixer、gulp-rename

gulpfile.js:

var gulp=require('gulp')
var postcss=require('gulp-postcss')
var nested=require('postcss-nested')
var cssnano=require('cssnano')
var apply=require('postcss-apply')
var autoprefixer=require('autoprefixer')
var rename=require('gulp-rename')

var option={
  browsers: ['Opera 12', 'IE 8']
}

gulp.task('postcss',function() {
  return  gulp.src('./test.pcss').pipe(postcss([autoprefixer(option),apply,nested])).on('error',function(error) {
    console.log(error)
    this.end()
  }).pipe(rename({extname:'.css'})).pipe(gulp.dest('./'))
})

上面咱们指定使用的浏览器,只是示例,使用'Opera 12', 'IE 8'这样的组合,咱们的源文件为test.pcss(这里我使用webstorm安装了postcss相关插件,.pcss后缀表示postcss样式文件,避免编辑器的语法错误提示),使用gulp-rename插件,最终生成的文件为当前目录下的test.css,执行任务,这里贴出源文件与生成后的文件对比:

clipboard.png

由上面的对比,咱们能够看出autoprefixer 自动增长/删除(固然也能够设置不删除) 前缀的功能,以及嵌套等的使用,下面一个问题:关于浏览器的兼容性检查呢?
使用doiuse,代码以下:

gulp.task('doiuse',function() {
  var option={
    browsers: [
      'ie >= 6',
    ],
    onFeatureUsage: function (usageInfo) {
      console.log(usageInfo.message)
    }
  }
  gulp.src('./test.css').pipe(postcss([doiuse(option)]))
})

给出运行结果的部分截图:

clipboard.png

这里咱们选择的浏览器范围是‘ie>=6’,doiuse执行的结果会告诉咱们css3 transition 并不被ie一些版本的浏览器支持。这样咱们就能够精确、统一地为咱们的css进行浏览器兼容检查。

最后一步:压缩:
代码:

gulp.task('cssnano',function() {
  gulp.src('./test.css').pipe(postcss([cssnano])).pipe(gulp.dest('./'))
})

上面test.css文件生成的结果以下:

clipboard.png

这里提醒你们注意的是,咱们本来css文件中,样式分开写的部分,cssnano为咱们作了合并操做,颜色属性的属性值部分,也换成了字节数比较少的16进制表示法。为咱们的css文件减小了一部分大小。

写一个插件

对于插件的编写文档也很详细,这里给一个本身平常用的简单示例,最近在写一个小程序项目,写小程序样式时使用一个单位:rpx,结合平常的编码习惯,写这个单位以为异常别扭,因而写了一个针对特定属性自动加单位的插件,代码以下:在gulpfile.js里增长以下代码:

function addunit(root) {
  // Transform CSS AST here
  var needAddProperties = ['width', 'height', 'top', 'left', 'bottom', 'right', 'margin-top',
                           'margin-bottom', 'margin-left', 'margin-right',
                           'padding-right', 'padding-left', 'padding-top', 'padding-bottom']
  root.walkDecls(function(decl) {
    if (needAddProperties.indexOf(decl.prop)!= -1) {
      decl.value.indexOf('%')== -1 && decl.value.indexOf('rpx')== -1 && (decl.value += 'rpx')
    }
  })
}

gulp任务中 postcss插件数组末尾增长一个本身写的插件 addunit:

gulp.task('postcss', function() {
  return gulp.src('./testaddunit.pcss').pipe(postcss([autoprefixer(option), apply, nested, addunit]))
             .on('error', function(error) {
    console.log(error)
    this.end()
  }).pipe(rename({ extname : '.css' })).pipe(gulp.dest('./'))
})

处理文件的先后对好比下:

clipboard.png

处理过程会根据须要自动为咱们添加单位。在实际开发中再配合postcss-scrib,咱们是能够这样写代码的:

clipboard.png

这里使用postcss-scrib插件咱们能够为属性自定义别名,结合gulp的watch功能,实时为咱们生成对应的css文件,也没有了编辑器语法错误提示,写css一会儿美好了不少。。。

end

相关文章
相关标签/搜索