本文概述
最近, PostCSS是在Web开发的前端进行巡回检查的工具。
PostCSS由Autoprefixer的创建者Andrey Sitnik开发。它是一个Node.js软件包, 开发为使用JavaScript转换所有CSS的工具, 因此比其他处理器可更快地构建。
尽管顾名思义, 它不是后处理器(也不是预处理器), 而是将特定于PostCSS(或更准确地说, 特定于PostCSS插件)的语法转换为Transpiler的原始CSS。
话虽如此, 这并不意味着PostCSS和其他CSS处理器不能一起工作。实际上, 如果你是CSS预处理/后期处理的新手, 那么将PostCSS与Sass结合使用可以为你省去很多麻烦, 我们将在稍后对此进行介绍。
PostCSS不能替代其他CSS处理器。而是将其视为可以在需要时派上用场的另一种工具, 这是工具集的另一项补充。
PostCSS的使用最近开始呈指数级增长, 如今已被Twitter, JetBrains和Wikipedia等一些最大的科技行业企业所使用。它的广泛采用和成功很大程度上归功于其模块化。
插件, 插件, 插件
PostCSS都是关于插件的。
它使你能够选择将要使用的插件, 抛弃不需要的依赖项, 并利用其他预处理器的基本特性为你提供快速而轻巧的设置来使用。此外, 它还允许你为工作流程创建更严格的自定义结构, 同时保持工作效率。
截至撰写本文之日, PostCSS的存储库包含200多个插件, 每个插件负责不同的任务。在PostCSS的GitHub存储库中, 插件按”解决全球CSS问题”, “今天使用将来的CSS”, “更好的CSS可读性”, “图像和字体”, “棉绒”和”其他”分类。
但是, 在plugins目录中, 你将找到更准确的分类。我建议你亲自去那里看看, 以更好地了解其中一些功能。它们相当广泛, 令人印象深刻。
你可能听说过最受欢迎的PostCSS插件Autoprefixer, 它是一个受欢迎的独立库。第二个最受欢迎的插件是CSSNext, 该插件可让你使用当今最新的CSS语法, 例如CSS的新自定义属性, 而无需担心浏览器支持。
并非所有的PostCSS插件都如此具有开创性。有些只是为你提供了可能与其他处理器一起提供的功能。以父选择器为例。使用Sass, 你可以在安装Sass时立即开始使用它。使用PostCSS, 你需要使用postcss-nested-ancestors插件。扩展或混合也一样。
那么, 使用PostCSS及其插件有什么优势?答案很简单-你可以选择自己的战斗。如果你觉得将要使用的Sass唯一部分是父选择器, 则可以避免在环境中实现诸如Sass库安装之类的工作来编译CSS的压力, 并通过使用仅PostCSS和postcss-nested-ancestors插件。
那只是PostCSS的一个用例示例, 但是一旦你自己进行检查, 毫无疑问, 你将意识到它的许多其他用例。
相关:*探索SMACSS:CSS的可扩展和模块化架构*
PostCSS基本用法
首先, 让我们介绍一些PostCSS基础知识, 并看看它的通常用法。尽管PostCSS与Gulp或Grunt等任务运行器一起使用时功能极为强大, 但也可以通过使用postcss-cli从命令行直接使用它。
让我们考虑一个简单的示例用例。假设我们想使用postcss-color-rgba-fallback插件, 以便为所有RGBA格式的颜色添加后备HEX值。
NPM安装完postcss, postcss-cli和postcss-color-rgba-fallback之后, 我们需要运行以下命令:
postcss --use postcss-color-rgba-fallback -o src/css/all.css dist/css/all.css
通过此指令, 我们告诉PostCSS使用postcss-color-rgba-fallback插件, 处理src / css / all.css中的所有CSS, 然后将其输出到dist / css / all.css。
好, 那很容易。现在, 让我们看一个更复杂的例子。
与任务运行者和Sass一起使用PostCSS
PostCSS可以很容易地整合到你的工作流程中。如前所述, 它与诸如Grunt, Gulp或Webpack之类的任务运行器完美集成, 甚至可以与NPM脚本一起使用。与以下Snip和Sass和Gulp一起使用PostCSS的示例很简单:
var gulp = require('gulp'), concatcss = require('gulp-concat-css'), sass = require('gulp-sass'), postcss = require('gulp-postcss'), cssnext = require('postcss-cssnext');
gulp.task('stylesheets', function () {
return (
gulp.src('./src/css/**/*.scss')
.pipe(sass.sync().on('error', sass.logError))
.pipe(concatcss('all.css'))
.pipe(postcss([
cssNext()
]))
.pipe(gulp.dest('./dist/css'))
)
});
让我们解构上面的代码示例。
它在一系列变量中存储了对所有所需模块(Gulp, Contact CSS, Sass, PostCSS和CSSNext)的引用。
然后, 它注册一个称为样式表的新Gulp任务。此任务监视扩展名为.scss的./src/css/中的文件(无论它们在子目录结构中的深度如何), Sass对其进行编译, 并将它们全部链接为单个all.css文件。
生成all.css文件后, 将其传递到PostCSS, 以将所有与PostCSS(和插件)相关的代码转换为实际CSS, 然后将生成的文件放置在./dist/css中。
好的, 因此使用任务运行器和预处理器设置PostCSS很好, 但这足以证明首先使用PostCSS是合理的吗?
让我们这样说:尽管Sass稳定, 成熟并且拥有庞大的社区, 但我们可能希望将PostCSS用于Autoprefixer之类的插件。是的, 我们可以使用独立的Autoprefixer库, 但是将Autoprefixer用作PostCSS插件的优点是可以在以后向工作流中添加更多插件, 并避免对大量JavaScript库的依赖。
这种方法还允许我们使用无前缀的属性, 并根据从API获取的值为它们加上前缀, 例如”我可以使用”中的值, 而仅使用Sass很难实现。如果我们试图避免可能不是最好的前缀代码的复杂混合, 这将非常有用。
如果你已经在使用Sass, 则将PostCSS集成到当前工作流程中的最常见方法是通过PostCSS及其插件传递.sass或.scss文件的编译输出。这将生成另一个CSS文件, 该文件同时具有Sass和PostCSS的输出。
如果你使用的是任务运行程序, 则在编译.sass或.scss文件(或所选预处理器的文件)之后, 使用PostCSS就像将其添加到当前的任务管道一样简单。
PostCSS与其他人玩得很好, 并且可以缓解我们开发人员每天都会遇到的一些主要痛点。
让我们看一下PostCSS(以及CSSNext和Autoprefixer等两个插件)和Sass一起工作的另一个示例。你可能具有以下代码:
:root {
$sass-variable: #000;
--custom-property: #fff;
}
body {
background: $sass-variable;
color: var(--custom-property);
&:hover {
transform: scale(.75);
}
}
该代码段具有原始CSS和Sass语法。自撰写本文之日起, 自定义属性仍处于候选推荐(CR)状态, 这是PostCSS的CSSNext插件在这里生效的地方。
该插件将负责将自定义属性等内容转换为当今的CSS。转换属性也会发生类似的情况, 该属性将由Autoprefixer插件自动添加前缀。先前编写的代码将导致类似:
body {
background: #000;
color: #fff;
}
body:hover {
-webkit-transform: scale(.75);
transform: scale(.75);
}
为PostCSS创作插件
如前所述, PostCSS的一个吸引人的功能是它允许的自定义级别。由于它的开放性, 如果你愿意编写JavaScript, 那么为PostCSS编写自己的自定义插件来满足你的特定需求是一项相当简单的任务。
PostCSS的工作人员有一个不错的清单, 如果你有兴趣开发插件, 请查看他们的推荐文章和指南。如果你觉得需要提出问题或进行讨论, 那么Gitter是最好的起点。
PostCSS的API具有相当活跃的Twitter关注者基础。加上本文前面提到的其他社区特权, 这就是使插件创建过程如此有趣和如此协作的原因。
因此, 要创建PostCSS插件, 我们需要创建一个Node.js模块。 (通常, node_modules /目录中的PostCSS插件文件夹前面带有诸如” postcss-“之类的前缀, 这是为了明确表明它们是依赖于PostCSS的模块。)
首先, 在新插件模块的index.js文件中, 我们需要包含以下代码, 这些代码将作为插件处理代码的包装:
var postcss = require('postcss');
module.exports = postcss.plugin('replacecolors', function replacecolors() {
return function(css) {
// Rest of code
}
});
我们将插件命名为replacecolors。插件将查找关键字deepBlackText并将其替换为#2e2e2e HEX颜色值:
var postcss = require('postcss');
module.exports = postcss.plugin('replacecolors', function replacecolors() {
return function(css) {
css.walkRules(function(rule) {
rule.walkDecls(function(decl, i) {
var declaration = decl.value;
if (declaration.indexOf('deepBlackText') !== -1) {
declaration = ‘color: #2e2e2e;’;
}
});
});
}
});
上一片段仅执行以下操作:
- 使用walkRules()可以遍历当前正在使用的.css文件中的所有CSS规则。
- 使用walkDecls()可以遍历当前.css文件中的所有CSS声明。
- 然后, 它将声明存储在声明变量中, 并检查其中是否包含字符串deepBlackText。如果是这样, 它将整个声明替换为以下CSS声明:color:#2e2e2e;。
插件准备好后, 我们可以直接从命令行使用它:
postcss --use postcss-replacecolors -o src/css/all.css dist/css/all.css
或者, 例如, 以如下方式加载到Guplfile中:
var replacecolors = require('postcss-replacecolors');
我应该抛弃当前的CSS处理器以使用PostCSS吗?
好吧, 这取决于你要寻找的东西。
经常同时使用Sass和PostCSS是很常见的, 因为新手可以更轻松地使用现成/后处理器提供的一些工具, 以及PostCSS插件的功能。并排使用它们还可以避免使用相对较新且最可能未知的工具来重建预定义的工作流, 同时提供一种方式来维护当前依赖于处理器的实现(例如Sass mixins, extends, 父选择器, 占位符选择器, 等等)。
相关:维护控制权:Pt Webpack and React指南。 2
给PostCSS一个机会
PostCSS是前端开发世界中的新事物。它已被广泛采用, 因为它本身不是预处理器/后处理器, 并且足够灵活以适应要插入的环境。
PostCSS的大部分功能都驻留在其插件中。如果你要寻找的是模块化, 灵活性和多样性, 那么这是完成任务的正确工具。
如果你使用的是任务运行程序或捆绑程序, 那么将PostCSS添加到当前流程中很可能是小菜一碟。查看安装和使用指南, 你可能会找到一种简便的方法将其与你正在使用的工具集成。
许多开发人员说, 至少在可预见的将来, 它会保留下来。 PostCSS可能会对我们当今CSS的结构产生重大影响, 并且有可能导致整个前端Web开发社区更大程度地采用标准。
相关:Sass Mixins:保持样式表干燥