Andrey Sitnik
Evil Martians
Russia
2 000 000 downloads per month
Users
Used Inside
UnCSS
CSS
Stringifier
Parser
Plugin 1
Plugin 2
New CSS
gulp.task('css', () => {
    let postcss = require('gulp-postcss');
    return gulp.src('src/*.css')
        .pipe( postcss([ plugin1, plugin2 ]) )
        .pipe( gulp.desc('build/') );
});Usage
postcss.plugin('my-plugin', function () {
    return function (css) {
        doSomething(css);
    };
});Plugin
.block {
    &_title {
        font-size: 200%;
    }
}Plugins like Less / Sass
.block_title {
    font-size: 200%;
}.foo {
  opacity: 0.8;
}Plugins for Fallbacks
.foo {
  opacity: 0.8;
  filter: alpha(opacity=80)\9;
}.foo {
    border: none;
}Plugins for Minify
.foo{border:0}.foo {
    margin-top: 10px;
    margin: 0 auto;
}Plugins for Lint
foo.css:3:5: margin overrides margin-top.
Is it accidentally mistake?
PostCSS vs. Less / Sass
PostCSS:
Less:
Mixins
Mixins
Transform
Lint
PostCSS vs. Gulp
PostCSS:
Gulp:
Parse
Transform
Fallbacks
Minify
Parse
Transform
Fallbacks
Minify
Parse
Parse
Less + PostCSS
return gulp.src('src/*.less')
    .pipe( less() )
    .pipe( postcss([]) )
    
    .pipe( gulp.desc('build/') );*.less
Less
CSS
PostCSS
Same CSS
Happy
product manager
postcss([
    require('autoprefixer')
])"last 2 version", "ie > 8"
+
.foo {
    user-select: none;
}.foo {
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
}No Mixins
.foo {
    transform: rotate(10deg);
}.foo {
    -webkit-transform: rotate(10deg);
            transform: rotate(10deg);
}Only Actual Prefixes
.foo {
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;
}.foo {
    border-radius: 5px;
}Clean Old Prefixes
postcss([
    require('postcss-csssimple'),
    require('autoprefixer')
])IE Fallbacks
.foo {
    display: inline-block;
}.foo {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}postcss-svg-fallback
.icon {
    background: url(icon.svg) no-repeat;
    background-size: 20px 20px;
}.icon {
    background: url(icon.svg) no-repeat;
    background-size: 20px 20px;
}
.no-svg .icon {
    background-image: url(icon-20x20.png);
}postcss([
    require('postcss-cssnext'),
    require('postcss-csssimple'),
    require('autoprefixer')
])@custom-media --phone (width <= 600px);
@media (--phone) {
    .promo-image {
        display: none;
    }
}“CSS 4” today
postcss-sprites
.comment {
    background: url(sprite/comment.png) no-repeat 0 0;
}
.bubble {
    background: url(sprite/bubble.png) no-repeat 0 0;
}.comment {
    background: url(sprite.png) no-repeat 0 0;
}
.bubble {
    background: url(sprite.png) no-repeat 0 -50px;
}postcss-url
.comment {
    background: url(comment.png);
}.comment {
    background: url(data:image/png;base64,
                    R0lGODdhMAAwA…);
}gulp.task('lint:css', function () {
    return gulp.src('src/*.less')
        .pipe( postcss([
            require('stylelint'),
            require('postcss-reporter'),
        ], {
            syntax: require('postcss-less')
        }) );
});Stylelint
Lead
Junior
Junior
Stylelint
Lead
RTLCSS
.logo {
    float: left;
    margin: 0 0 0 10px;
}.logo {
    float: right;
    margin: 10px 0 0 0;
}RTLCSS
Advanced Topics
PreCSS
twitter.com/ andreysitnik
twitter.com/ postcss
gitter.im/ postcss/postcss