PostCSS

1. Mở đầu

Nếu công việc của bạn liên quan tới front end, thì hẳn bạn đã dùng hoặc chí ít cũng nghe nói tới các CSS preprocesor như Sass hay Less. Thế nhưng số người biết đến và sử dụng post-processing tool như PostCSS lại còn rất hạn chế.

Trong bài viết này, mình sẽ giới thiệu PostCSS là gì, và lợi ích khi sử dụng nó.

2. Giới thiệu chung

PostCSS là một công cụ dùng JavaScript để xử lý CSS. Thực tế, PostCSS chỉ là một số các API phục vụ cho hằng hà sa số các plugin cho nó.

Có thể liên tưởng tới JavScript ecosystem như thế này: Sass hay Less giống như một ngôn ngữ mới, compile ra CSS tương tự như CoffeeScript hay TypeScript vậy; còn PostCSS cùng các plugin của mình giống Babel, nó chỉ "biến đổi" CSS, và cùng với một vài plugin của bên dưới ta có thể sử dụng các cú pháp CSS của tương lai giống như ES6Babel hiện nay vậy.

3. Cài đặt

Bởi PostCSS là một công cụ viết bằng JavaScript nên ta sẽ sử dụng nó cùng với task runner như Gulp hay Grunt.

3.1 Cài đặt với gulp

Trước hết, ta cần cài PostCSS module vào trong project, sử dụng npm:

npm i gulp-postcss -D

Và ở trong Gulpfile.js, ta sẽ định nghĩa một task để chạy module này:

var postcss = require('gulp-postcss');

gulp.task('styles', function () {
    return gulp.src('path/to/dev/style.css')
        .pipe(postcss([]))
        .pipe(gulp.dest(path/to/prod))
});

Sau đó, ta có thể chạy task với gulp styles

3.2 Cài đặt với grunt

Để cài đặt PostCSS module, ta dùng câu lệnh:

npm i grunt-postcss -D

Sau khi package đã được cài đặt xong, ta có thể sử dụng nó trong Gruntfile như sau:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    styles: {
      options: {
        processors: []
      },
      dist: {
        files: [{
          expand: true,
          cwd: 'dev/',
          src: ['**/*.css'],
          dest: 'prod/'
        }]
      }
    }
  });

  // Load post-css.
  grunt.loadNpmTasks('grunt-postcss');

};

Tương tự như với grunt, ta chạy task bằng grunt styles

4. Một số plugin

4.1 Cách cài đặt plugin

Trước hết cần cài plugin bằng npm, ví dụ với autoprefixer:

npm i autoprefixer -D

Sau đó ở trong Gruntfile hay Gulpfile, ta sẽ require plugin và truyền nó vào postcss như một mảng.

Grunt:

var processorArray = [
    require('postcss-plugin')()
];

styles: {
      options: {
        processors: processorArray
      },
      dist: {
        src: 'path/to/dev/style.css',
        dest: 'path/to/prod/style.css'
      }
    }

Và với Gulp:

var processorArray = [
    require('postcss-plugin')()
];

gulp.task('styles', function () {
    gulp.src('path/to/dev/style.css')
        .pipe(postcss(processorArray))
        .pipe(gulp.dest('path/to/prod'))
});

4.2 Autoprefixer

Plugin này tự động thêm vendor prefix cho chúng ta khi cần thiết.

Như ở phần trên, để cài plugin ta chạy câu lệnh:

npm i autoprefixer -D

Ta có thể cấu hình loại browser nào ta cần support. Danh sách các option có thể xem tại https://github.com/ai/browserslist

Giờ thêm Autoprefixer vào mảng các processor nhé:

var processorsArray = [
  require('autoprefixer')({ browsers: ['last 2 versions', 'ie 6-8', 'Firefox > 20']  })
];

Với cấu hình này, khi ta sử dụng flexbox:

.item {
  display: flex;
  flex-flow: row wrap;
}

thì css đầu ra sẽ được tự thêm prefix tương ứng:

.item {
  display: -webkit-flex;
  display: -ms-flexbox;
  display: -webkit-box;
  display: flex;
  -webkit-flex-flow: row wrap;
      -ms-flex-flow: row wrap;
          flex-flow: row wrap;
}

4.3 CssNext

CSSNext cho phép chúng ta dùng các feature của CSS4 ngay bây giờ. Module này sẽ biến đổi các chức năng của CSS4 này thành CSS3 được hỗ trợ bởi các browser hiện nay.

Đề cài CSSNext ta chạy:

npm i cssnext -D

Và thêm vào danh sách processor:

var processorsArray = [
  require('cssnext')()
];

Khi browser đã hỗ trợ CSS4, ta chỉ việc bỏ plugin này thôi.

Ví dụ CSS đầu vào:

// Custom Variables
:root {
  --linkColour: purple;
}

a {
  color: var(--linkColour);
}

// Custom media queries with ranges
@custom-media --only-medium-screen (width >;= 500px) and (width <= 1200px);

@media (--only-medium-screen) {
  /* Medium viewport styles */
}

// Custom selectors
@custom-selector :--enter :hover, :focus;
@custom-selector :--input input, .input, .inputField;

a:--enter {
  /* Enter styles go here */
}

:--input {
  /* Input field styles go here */
}

Và kết quả đầu ra:

a {
  color: purple;
}

@media (min-width:500px) and (max-width:1200px){
  body{
    background:#00f;
  }
}

a:focus,a:hover{
  background:#00f;
}

.input, .inputField, input{
  background:red;
}

5. Tài liệu tham khảo