jinlong.github.com icon indicating copy to clipboard operation
jinlong.github.com copied to clipboard

快速上手 PostCSS

Open jinlong opened this issue 6 years ago • 0 comments

👻 PostCSS 是什么鬼?

A tool for transforming CSS with JavaScript

CSS 中的 Babel

并不是什么新技术,出来很久了,https://segmentfault.com/a/1190000003909268

不要怕,这是门旧技术,你学的动 😜

现在用也不晚,因为浏览器还需要它的帮助

🤔 PostCSS 有什么好?

与同类工具对比

别给我谈 LESS、SASS,老夫只撸 CSS

条件 LESS / SASS PostCSS
开发模式 使用它们自己发明的语法 使用 CSS 标准语法
学习成本 学习独创语法和 CSS 标准语法 学习 CSS 标准语法

定制插件

PostCSS 提供了一个解析器,它能够将 CSS 解析成抽象语法树(AST),可以基于它的 API 开发插件

😳 PostCSS 能干啥?

自动加浏览器前缀

不知不觉你就用了

Autoprefixer(使用最广的 postcss 插件)

/*CSS input*/
:fullscreen {
}

/*CSS output*/
:-webkit-:full-screen {
}
:-moz-:full-screen {
}
:full-screen {
}

使用未来的 CSS

PostCSS Preset Env

img {
  --some-length: 32px;

  height: var(--some-length);
  width: var(--some-length);
}

CSS 模块化

CSS Modules 利于模块化,防止命名冲突

/*CSS input*/
.name {
  color: gray;
}

/*CSS output*/
.Logo__name__SVK0g {
  color: gray;
}

更多插件

https://github.com/postcss/postcss#plugins

🤓 PostCSS 怎么用?

官方 Github:https://github.com/postcss/postcss

Webpack 配置 Autoprefixer

安装

npm i -D autoprefixer

可以搭配 postcss-loader 使用

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader", "postcss-loader"]
            }
        ]
    }
}

创建 postcss.config.js 文件

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

浏览器列表配置

Autoprefixer 使用 Browserslist,可以指定项目面向哪些浏览器用户(参见最佳实践

最佳实践是提供 .browserslistrc 配置或者在 package.json 添加 browserslist 属性,这些配置项可以跟其他工具共享,例如 babel-preset-env 或 Stylelint

可配注释

.a {
    transition: 1s; /* 加前缀 */
}

.b {
    /* autoprefixer: off */
    transition: 1s; /* 不加前缀,禁用整个代码块 */
}

.c {
    /* autoprefixer: ignore next */
    transition: 1s; /* 不加前缀 */
    mask: url(image.png); /* 加前缀 */
}

递归使用

/* autoprefixer: off */
@supports (transition: all) {
    /* autoprefixer: on */
    a {
        /* autoprefixer: off */
    }
}

参数配置

基本不用手配,完整配置见这里:https://github.com/postcss/autoprefixer#options

使用未来的 CSS

Use tomorrow’s CSS today.

Webpack 配置 postcss-preset-env

安装

npm i -D postcss-preset-env

在 webpack 配置中新增配置

import postcssPresetEnv from 'postcss-preset-env';

export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          { loader: 'postcss-loader', options: {
            ident: 'postcss',
            plugins: () => [
              postcssPresetEnv(/* options */)
            ]
          } }
        ]
      }
    ]
  }
};

也可在 postcss.config.js 中配置

module.exports = {
  plugins: [
    require('postcss-preset-env')({
      stage: 0
    })
  ]
}

参数配置

stage

区间为 0 到 4,stage 决定哪些 CSS 特性需要被编译;设置为 false,代表所有特性都不编译。

默认启用 Stage 2 特性

stage 划分见这里:https://cssdb.org/#staging-process

开关特性

特性归属哪个 stage?https://cssdb.org/

postcssPresetEnv({
  /* use stage 3 features + css nesting rules */
  stage: 3,
  features: {
    'nesting-rules': true
  }
})

浏览器列表配置

同样支持标准的 .browserslistrc 配置或者在 package.json 添加 browserslist 属性

px 转 rem

使用 postcss-plugin-px2rem 插件

Webpack 如何配置

npm i -D postcss-plugin-px2rem

vue-loader配置中添加配置

const px2rem = require('postcss-plugin-px2rem');

export default {
  module: {
    rules: [
    {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            postcss: ['css-hot-loader'].concat(ExtractTextPlugin.extract({
              use: cssOptions,
              fallback: styleLoaderOptions
            }))
          },
          postcss: function () {
            return [
              px2rem({rootValue: 37.5})
            ];
          }
        }
      }
    ]
  }
}

注意事项

  • 配合淘宝的 flexible.js 使用
  • rootValue 设置:1x 设计稿,设置 37.5;2x 设计稿,设置为 75
  • 页面根节点的基准值要跟 rootValue 一致

px2rem 版本众多

  1. px2rem 原版:https://github.com/songsiqi/px2rem
  2. postcss plugin 实现:https://github.com/songsiqi/px2rem-postcss
  3. webpack loader 实现:https://github.com/Jinjiang/px2rem-loader

延伸阅读:

jinlong avatar Sep 05 '18 09:09 jinlong