前端知识库(lizh)
  • README
  • Bugs
    • 前端调试随笔
    • 浏览器常见问题概览
    • 浏览器兼容问题概览
    • HTML常见问题概览
    • CSS常见问题概览
    • JS常见问题概览
    • 移动端兼容性问题概览
    • 微信小程序开发
    • NodeJs常见问题概览
    • Mac常见问题概览
    • 微信开发遇坑指南
    • Npm包常见问题概览
    • 其他问题汇总
  • Css探索系列
    • CSS基础知识
    • CSS常见问答
    • CSS常见问答02
    • CSS应用示例
    • CSS应用示例02
    • 由Z Index引发的层叠上下文思考
    • 由浮动塌陷引发的块级格式上下文思考
    • CSS探索系列 Flex布局
    • CSS探索系列 Margin
    • CSS探索系列 Auto关键字
    • CSS探索系列 Gradient
    • CSS探索系列 Line Height
    • CSS探索系列 元素居中
    • CSS探索系列 动画
    • 为什么使用PostCSS处理CSS?
    • 重新认识伪类与伪元素
    • 自定义表单伪元素样式
    • 如何理解Css中的Display属性
    • 视口和软键盘对视口的影响
    • 关于Css
  • Frontend
    • 00 关于Web前端
    • 01 前端知识概览
    • 02 常用前端库概览
    • 基础 00 前端常见问题01
    • 基础 01 浏览器缓存
    • 基础 02 浏览器工作原理
    • 基础 03 谈谈前端跨源问题及解决方法
    • 进阶 01 Web性能优化
    • 进阶 02 搜索引擎优化(SEO)
    • 进阶 03 前端模块化编程
    • 进阶 04 规范代码:Linter、Prettier、EditorConfig
    • 进阶 11 前端自动化测试
    • 高级 01 前端安全
    • Vue2.X原理篇
    • Vue3初步了解及迁移指南
    • 重读Vue教程
    • React17.X原理篇
    • 你必须知道的React问题
    • 重读React教程
    • 聊一聊Cookie的一些问题
    • 如何理解HTTP响应的状态码
    • HTTP的历史演变及概述
    • Webpack4.X原理篇
    • Webpack基础入门篇
    • Webpack构建优化篇
    • TypeScript使用指南
    • 代码规范
      • 前端规范
      • HTML
      • CSS
      • JS
  • Html探索系列
    • HTML基础知识
    • HTML基础知识02
    • HTML常见问答
    • HTML经典实践用例
    • HTML元素的宽高及位置详解
    • Video元素的使用和常见问题总结
    • Html探索系列 Meta标签
    • DOCTYPE:文档类型与浏览器模式
    • DHTML(动态网页)简介
    • HTML标签详解
    • HTML布局的几种方式
    • HTML全局属性
    • 关于Html
  • Js探索系列
    • 基础知识
    • 常见问答
    • 应用示例
    • 趣味示例
    • 基础篇 05 AJAX
    • 基础篇 06 Window对象
    • 基础篇 07 Error、JSON、Math、Console对象
    • 基础篇 08 History、URL、Screen、Navigator、Location对象
    • 基础篇 09 文档对象模型(DOM)
    • 基础篇 10 Document对象
    • 基础篇 11 Element对象
    • 基础篇 12 Event对象
    • 基础篇 13 键盘、鼠标、触摸事件
    • 基础篇 15 CSS对象模型(CSSOM)
    • 进阶篇 01 Prototype对象和继承
    • 进阶篇 02 Promise对象
    • 进阶篇 07 迭代器(Iterator)
    • 进阶篇 08 Generator和Async函数
    • 进阶篇 09 JavaScript异步编程
    • Date对象和日期时间字符串格式
    • Canvas基础入门篇
    • Canvas进阶篇
    • SVG基础入门篇
    • 四种判断数据类型方法的优缺点
    • 深入理解JavaScript的浅拷贝和深拷贝
    • 谈谈JavaScript的作用域和上下文
    • 复制内容到剪贴板
    • 关于Javascript
  • NodeJs
    • 关于Node.Js
    • Node.Js:三种调试方法
    • Npm包管理器简介及一些机制
    • NPM:Package.Json详解(中文)
    • NPM:从零开始,开发一个软件包
    • NPM:常用命令
    • Node.Js:Fs(文件系统)
    • Node.Js:Global(全局变量)
    • Node.Js:HTTP
    • Node.Js:Module(模块)
    • Node.Js:Path(路径)
    • Node.Js:Readline(逐行读取)
  • Research
    • 极细边框(1px边框)实现方式
    • 如何监控前端异常?
    • H5页面跳转和刷新
    • Web主题切换和个性化定制方法总结
    • Vue SSR(服务端渲染)的简单实现
    • 基于Create React App打造代码规范化的React+Ts项目
    • H5可视化编辑
    • Web常用功能
    • Javascript加密混淆
    • Vue如何导入TypeScript
    • 移动端PDF预览
    • 纯CSS绘制箭头
    • 网站性能测量和优化方法
  • Tech
    • GOOGLE浏览器的搜索技巧
    • Curl的用法指南
    • Sublime3插件篇
    • Charles安装及使用
    • Nginx基础使用
    • 排序算法(Javascript)
    • 代码整洁之道(摘录笔记)
    • Java的24种设计模式与7大原则
    • 观察者和发布订阅模式
  • Tools
    • Git
      • Git基础教程
      • Git常见问题
    • Gitbook
      • Gitbook入门篇
      • Gitbook插件篇
      • Gitbook进阶篇
由 GitBook 提供支持
在本页
  • postcss是什么?
  • 为什么选择postcss?
  • postcss的使用
  • 基于webpack,创建测试项目
  • 常用插件
  • Autoprefixer
  • postcss-nesting 、postcss-nested
  • postcss-import
  • postcss-preset-env
  • cssnano
  • postcss-apply
  • postcss-mixins
  • postcss-px2rem-exclude
  • 参考文档

这有帮助吗?

  1. Css探索系列

为什么使用PostCSS处理CSS?

上一页CSS探索系列 动画下一页重新认识伪类与伪元素

最后更新于3年前

这有帮助吗?

postcss是什么?

PostCSS是一个用 JavaScript 工具和插件转换 CSS 代码的工具。

PostCSS并不是一门语言,而是一个类似于webpack的工具,它支持很多插件,来达到便捷的编译效果,组成一个CSS编译/lint/autoprefixer的生态圈。它的作者是,一家致力于技术研究与网站外包开发的公司。其后端技术栈偏重于Ruby,而前端从 React 到 Node 都有涉猎。

PostCSS 本身是一个功能比较单一的工具。它提供了一种方式用 JavaScript 代码来处理 CSS。它负责把 CSS 代码解析成抽象语法树结构(Abstract Syntax Tree,AST),再交由插件来进行处理。

插件基于 CSS 代码的 AST 所能进行的操作是多种多样的,比如可以支持变量和混入(mixin),增加浏览器相关的声明前缀,或是把使用将来的 CSS 规范的样式规则转译(transpile)成当前的 CSS 规范支持的格式。从这个角度来说,PostCSS 的强大之处在于其不断发展的插件体系。

目前 PostCSS 已经有 200 多个功能各异的插件。开发人员也可以根据项目的需要,开发出自己的 PostCSS 插件。

实际上,PostCSS 的主要功能只有两个:

  • 第一个就是前面提到的把 CSS 解析成 JavaScript 可以操作的 AST,

  • 第二个就是调用插件来处理 AST 并得到结果。

因此,**不能简单的把 PostCSS 归类成 CSS 预处理或后处理工具。**PostCSS 所能执行的任务非常多,同时涵盖了传统意义上的预处理和后处理。

为什么选择postcss?

随着前端工程化的不断完善,CSS 预处理器已经成为项目中不可缺少的部分,很多人在项目技术选型阶段就会先选择一个 CSS 预处理器,绝大部分前端工程的脚手架也内置了一系列的 CSS 预处理的模版。

CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成 CSS 的程序。

市面上有很多 CSS 预处理器可供选择,且绝大多数 CSS 预处理器会增加一些原生 CSS 不具备或不完善的高级特性,这些特性让 CSS 的结构更加具有可读性且易于维护。当前社区代表的 CSS 预处理器 主要有以下几种:

  • :2007 年诞生,最早也是最成熟的 CSS 预处理器,拥有 Ruby 社区的支持和 Compass 这一最强大的 CSS 框架,目前受 LESS 影响,已经进化到了全面兼容 CSS 的 SCSS。

  • :2009年出现,受 SASS 的影响较大,但又使用 CSS 的语法,让大部分开发者和设计师更容易上手,在 Ruby 社区之外支持者远超过 SASS,其缺点是比起 SASS 来,可编程功能不够,不过优点是简单和兼容 CSS,反过来也影响了 SASS 演变到了 SCSS 的时代,著名的 Twitter Bootstrap 就是采用 LESS 做底层语言的。

  • :Stylus 是一个CSS的预处理框架,2010 年产生,来自 Node.js 社区,主要用来给 Node 项目进行 CSS 预处理支持,所以 Stylus 是一种新型语言,可以创建健壮的、动态的、富有表现力的 CSS。比较年轻,其本质上做的事情与 SASS/LESS 等类似,

相比其他的 CSS 预处理器,postcss 优势主要体现在以下几个方面:

  • 根据你需要的特性进行模块化,而不是像 less 或者 scss 一样的全家桶。

  • 多样化的功能插件,创建了一个生态的插件系统

  • 可以自己编写postcss插件

  • 既可以写正常的CSS,也可以结合 LESS 或者 SASS 一起编写

  • 可以与许多流行工具无缝部署,例如 webpack、gulp、codepen 等

  • 对 Source Map 支持更好

一句话来概括PostCSS:CSS编译器能够做到的事情,它也可以做到,而且能够做得更好

postcss的使用

PostCSS的一大特点是,具体的编译插件甚至是CSS书写风格,可以根据自己的需要进行安装,选择自己需要的特性:嵌套,函数,变量。自动补全,CSS新特性等等,而不是像less或者scss一样的大型全家桶。因此,不需要再专门去学习less或者scss的语法,只要选择自己喜欢的特性,可以只写 CSS 文件,但依旧可以写嵌套或者函数,然后选择合适的插件编译它就行了。

安装:npm i -D postcss-loader

postcss的配置:

  • webpack.config.js,优先级最高

    // webpack.config.js
    {
        test: /\.css$/,
        use: [
            'style-loader',
            'css-loader',
            {
                loader: 'postcss-loader',
                options: {
                    ident: 'postcss',
                    plugins: (loader) => [
                        require('postcss-import')({ root: loader.resourcePath }),
                        require('postcss-preset-env')(),
                        require('cssnano')()
                    ]
                }
            }
        ]
    }
  • postcss.config.js或者.postcssrc.js

    // postcss.config.js
    module.exports = ({ file, options, env }) => ({
        parser: file.extname === '.sss' ? 'sugarss' : false,
        plugins: {
            'autoprefixer': {},
            'postcss-import': { root: file.dirname },
            'postcss-preset-env': options['postcss-preset-env'] ? options['postcss-preset-env'] : false,
            'cssnano': env === 'production' ? options.cssnano : false
        }
    })
  • .postcssrc

    {
        "plugins": {
            "postcss-plugin": {}
        }
    }
  • package.json 中的 postcss,优先级最低

    {
        "postcss": {
            "plugins": {
    			"postcss-plugin": {}
            }
        }
    }

基于webpack,创建测试项目

鉴于现在webpack也越来越火,所以之后的配置主要是借助于postcss-loader,将PostCSS的生态圈依托在webpack之下。

安装:

npm i webpack webpack-cli -g

npm i webpack

npm i css-loader postcss-loader mini-css-extract-plugin -D

项目结构如下:

- build
  - webpack.postcss.config.js
- src
  - index.css
  - index.js
- package.json
- postcss.config.js
// webpack.postcss.config.js
const webpack = require('webpack')
const Path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const webpackConfig = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: Path.resolve(__dirname, '../dist'),
        filename: 'index.js'
    },
    module: {
        rules: [
            {
                // 使用 PostCSS 处理 CSS 文件
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'index.css',
            chunkFilename: 'chunkIndex.css',
        })
    ]
}
webpack(webpackConfig, err => {})

MiniCssExtractPlugin 不能与 style-loader 一起使用

webpack(webpackConfig, err => {}),要传回调函,可以为空

// index.js
import './index.css'
/*index.css*/
.hello {
    box-sizing: border-box;
}
// package.json
{
    ...
    "scripts": {
		"postcss": "node build/webpack.postcss.config.js"
    },
    ...
}
// postcss.config.js
module.exports = ({ file, options, env }) => ({
    plugins: {
    }
})

常用插件

安装:npm i autoprefixer -D

  • postcss.config.js:

    //postcss.config.js
    module.exports = ({ file, options, env }) => ({
        plugins: {
            "autoprefixer": {
                "overrideBrowserslist": [
                    "> 0.1%",
                    "last 2 versions",
                    "Android >= 3.2",
                    "Firefox >= 20",
                    "iOS >= 7",
                    "chrome >  20"
                ]
            }
        }
    })
  • package.json 增加如下配置:

    {
        "browserslist": [
            "> 1%",
            "last 2 versions",
            "Android >= 3.2",
            "Firefox >= 20",
            "iOS >= 7",
            "chrome >  20"
        ]
    }
  • 根目录下加.browerslistrc配置文件:

    # 注释是这样写的,以#号开头
    "> 1%",
    "last 2 versions",
    "Android >= 3.2",
    "Firefox >= 20",
    "iOS >= 7",
    "chrome >  20"
/* 输入 src/index.css */
.autoprefixer {
    box-sizing: border-box;
}

/* 输出 dist/index.css */
.autoprefixer {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
}

支持css的嵌套写法。

安装: npm i postcss-nesting -D

安装:npm i postcss-nested -D

他们两个的区别是:

建议是使用 postcss-nesting ,遵循W3C规则。

//postcss.config.js
module.exports = ({ file, options, env }) => ({
    plugins: {
        "postcss-nesting": {}
    }
})
/*postcss-nesting,嵌套样式前需要加&符号*/
/*postcss-nested,正常样式前不需加&符号,伪类前还是要加*/
/*输入*/
.postcss_nesting {
    & sub_class {
        width: 100%;
    }
    & a {
        color: red;
    }
}

/*输出*/
.postcss_nesting sub_class {
    width: 100%;
}
.postcss_nesting a {
    color: red;
}

允许css通过@ import内联其他css模块。

安装: npm i postcss-import -D

// postcss.config.js
module.exports = ({ file, options, env }) => ({
    plugins: {
        "postcss-nesting": {}
    }
})

新增一个import.css文件,在index.css中导入:

/*import.css*/
.import {
    color: red;
}
.import_sub {
    width: 100%;
}
/*index.css*/
@import './import.css';

最终输出到dist/index.css:

/*import.css*/
.import {
    color: red;
}
.import_sub {
    width: 100%;
}

安装:npm i postcss-preset-env -D

postcss-preset-env 已经内置了 autoprefixer、postcss-nesting/postcss-nested、postcss-import 等相关功能。

//postcss.config.js
module.exports = {
    plugins: {
        "postcss-preset-env": {
            features: {
                "custom-properties": {
                    preserve: false,
                    variables: {}
                },
                "nesting-rules": true
            }
        }
    }
}

安装:npm i cssnano -D

cssnano会采用格式良好的CSS并通过许多有针对性的优化来运行它,以确保最终结果对于生产环境而言尽可能小。

//postcss.config.js
module.exports = {
    plugins: {
        "cssnano": {
            preset: ["default", {
                // 禁止插件对自定义动画名称的重命名
                reduceIdents: false,
                // 禁用postcss重写z-index值
                zindex: true
            }]
        }
    }
}
/*输入*/
.autoprefixer {
    box-sizing: border-box;
}
.postcss_nesting {
    & sub_class {
        width: 100%;
    }
    & a {
        color: red;
    }
}
.cssnano {
    font-size: 16px;
    z-index: 1000;
}

/*输出*/
.autoprefixer{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.postcss_nesting sub_class{width:100%}.postcss_nesting a{color:red}.cssnano{font-size:16px;z-index:1000}

允许您将一组属性存储在指定的定制属性中,然后在其他样式规则中引用它们。

您正在使用@apply 规则和自定义属性集。该功能将不会包含在 postcss-cssnext 的下一个主要版本中。这很可能不会得到来自浏览器供应商的更多支持,因为该规范尚未被认可,并且正在讨论替代解决方案。

安装:npm i postcss-apply -D

//postcss.config.js
module.exports = {
    plugins: {
        "postcss-import": {},
        "postcss-apply": {}
    }
}

新增一个apply.css,引入到index.css:

/*apply.css*/
:root {
	--no-wrap: {
		width: 100%;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}
/*index.css*/
@import './apply.css';
.apply {
    color: green;
    @apply --no-wrap;
}

最终输出到dist/index.css:

/*dist/index.css*/
.apply {
    color: green;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

postcss-apply 要跟 postcss-import 一起使用

样式混入文件中。

安装:npm i postcss-mixins -D

//postcss.config.js
module.exports = ({ file, options, env }) => ({
  plugins: {
    "postcss-mixins": {},
  }
})
/*输入*/
@define-mixin icon $name, $color: blue {
    .icon.is-$(name) {
        color: $color;
    }
    .icon.is-$(name):hover {
        color: white;
        background: $color;
    }
}
  
@mixin icon twitter {
    background: url(twt.png);
}

/*输出*/
.icon.is-twitter {
    color: blue;
}

.icon.is-twitter:hover {
    color: white;
    background: blue;
}

安装:npm i postcss-px2rem -D

安装:npm i postcss-px2rem-exclude -D

//postcss.config.js
module.exports = {
    "plugins": {
        "postcss-px2rem-exclude": {
            remUnit: 75,
            exclude: /node_modules|folder_name/i
        }
    }
}
/*输入*/
.px2rem {
    width: 100px;
    font-size: 30px;
}

/*输出*/
.px2rem {
    width: 1.333333rem;
    font-size: 0.4rem;
}

参考文档

拥有极高的处理性能()

到目前,PostCSS有200个多个插件。你可以在或找到它们。你也可以自己。

利用从 Can I Use 网站获取的数据为 CSS 规则添加特定厂商的前缀。 自动获取浏览器的流行度和能够支持的属性,并根据这些数据帮你自动为 CSS 规则添加前缀。

我们可以用以下方法,对插件配置参数,( ):

具体配置参数,可以参考

、

: W3C nested selectors,遵循W3C的写法,每个嵌套的样式前面都需要一个&(注意符号后面有个空格)

: Sass-like nested selectors,不需要加&符号

帮你将现代 CSS 语法转换成大多数浏览器都能理解的东西,根据你的目标浏览器或运行时环境来确定你需要的 polyfills,基于 。

具体参数可查看 或者

Euil Martians
Sass
Less
Stylus
3倍以上的处理速度
插件列表
搜索目录
开发PostCSS插件
Autoprefixer
Autoprefixer
Browserslist,指定目标浏览器范围
前端工程基础知识点--Browserslist (基于官方文档翻译)
postcss-nesting
postcss-nested
postcss-nesting
postcss-nested
postcss-import
postcss-preset-env
cssdb 实现
postcss-preset-env
feature
cssnano
postcss-apply
postcss-mixins
postcss-px2rem-exclude
postCss 初识 (文章较长,需要耐心)
2019年,你是否可以抛弃 CSS 预处理器?