postcss插件开发
在上一教程中,我们介绍了如何使用出色的预处理包“ PreCSS”。 在本教程中,我们将以不同的方式进行基于PostCSS的预处理。 安装精选的插件以自定义从头开始构建预处理器。
我将带您完成我个人认为是语言扩展插件的绝佳组合的设置。 但是,当涉及到滚动自己的预处理器时,您可能选择仅使用我们在此介绍的某些插件,或者您可能根本不选择任何插件,而是选择其他选项。
这就是这个过程的美。 您可以选择自己的预处理器。 本教程的目的是为您提供组装PostCSS预处理器的经验,并介绍当前可用插件的功能,以便您自己决定要使用的插件。
让我们开始!
设置您的项目
您需要做的第一件事是根据您的喜好将项目设置为使用Gulp或Grunt。 如果您没有一个或另一个偏好,我建议您使用Gulp,因为您将需要更少的代码来达到相同的目的。
您可以在之前的教程中了解如何为PostCSS设置Gulp或Grunt项目
分别。
但是,如果您不想从头开始手动设置项目,则可以下载本教程附带的源文件 ,并将提供的Gulp或Grunt入门项目提取到一个空项目文件夹中。
然后,在终端或命令提示符指向该文件夹的情况下,运行命令npm install
。
插件安装注意事项
本教程将假定您已遵循本系列中的先前文章,并且现在熟悉如何将插件安装到项目中并通过Gulpfile或Gruntfile加载它。
重要! 在学习过程中,请确保按照本教程中看到的顺序将插件加载到Gulpfile / Gruntfile中。 加载顺序在PostCSS中很重要,它可以使一切平稳运行。
添加部分导入
首先要开始的是将我们的自定义预处理器放在一起,就是导入。 在之前的有关 使用PreCSS 进行缩小和优化以及预处理的教程中,您已经看到@import
样式表的PostCSS内联。 导入将在此预处理器中使用的方式没有什么不同。
上面我们谈到了加载顺序在PostCSS中很重要的事实,在这里我们找到了第一个示例。 我们希望确保第一步都内联所有@import
文件,以便我们将项目的所有代码放在一个地方,以便其余插件可以运行。
例如,我们可以将所有变量存储在部分文件中,并使用@import
将其引入到主样式表中。 如果我们没有运行先内联@import
文件的插件,那么我们的变量将不会被导入,因此无法用于其余的处理。
首先,将Gulpfile源文件更改为“ style.css”
因为我们将开始导入局部数据,所以在添加导入功能之前,我们需要对Gulpfile进行一些调整。
注意 :如果使用Grunt,则此阶段无需进行任何更改。
目前,我们已经在“ src”文件夹中找到了任何“ .css”文件,但是我们不想意外地编译部分文件。 我们将所有内容导入“ style.css”文件,因此它是唯一需要编译的文件。
找到这一行:
return gulp.src('./src/*.css')
...并将其更改为:
return gulp.src('./src/style.css')
使用的导入插件:
- Maxime Thirouin撰写的postcss-import: https : //github.com/postcss/postcss-import
这与我们在“用于缩小和优化”教程中使用的插件相同,并且在PreCSS中也使用了该插件,因此您在这一点上会有点熟悉。
将插件安装到项目中,然后在“ src”文件夹中创建一个名为“ _vars.css”的文件,并向其中添加一些基本测试代码。 请注意,我们尚未添加变量功能,因此仅添加一些简单CSS,例如:
.test {
background: black;
}
现在,通过在第一行添加以下代码,将新的变量文件导入到主“ src / style.css”文件中:
@import "_vars";
编译代码,然后检查“ dest / style.css”文件,您现在应该看到它包含“ _vars.css”文件中的代码。
添加混入
使用的Mixins插件:
- Andrey Sitnik撰写的postcss-mixins: https : //github.com/postcss/postcss-mixins
注意 :此插件必须在我们将要使用的postcss-nested和postcss-simple-vars插件之前执行。
继续安装postcss-mixins,然后将以下代码添加到“ src / style.css”文件中:
@define-mixin icon $network, $color {
.button.$(network) {
background-image: url('img/$(network).png');
background-color: $color;
}
}
@mixin icon twitter, blue;
编译后,您的“ dest / style.css”应添加以下已编译的代码:
.button.twitter {
background-image: url('img/twitter.png');
background-color: blue;
}
我们在这里使用的postcss-mixins插件与PreCSS中使用的插件相同。 我们在PreCSS上的教程中介绍了如何使用它,因此,有关其语法的完整详细信息,请查看上一教程的“ Mixins”部分。
其他Mixin插件选项:
- Andy Jansson撰写的postcss-sassy-mixins: https : //github.com/andyjansson/postcss-sassy-mixins
如果您在创建混入文件时希望使用Sass语法,请查看Andy Jansson的postcss-sassy-mixins插件,该插件的功能与postcss-mixins相同,但使用@mixin
语法定义一个混入,并使用@include
来使用之一。
添加“ for”循环
“ for”循环插件使用:
- 由Anton Yakushev撰写的postcss-for: https : //github.com/antyakushev/postcss-for
注意 : postcss-for插件是另一个必须在postcss-nested和postcss-simple-vars之前执行的插件。
安装postcss-for插件,然后将以下代码添加到“ src / style.css”文件中,以测试其是否按预期工作:
@for $i from 1 to 3 {
p:nth-of-type($i) {
margin-left: calc( 100% / $i );
}
}
它应该编译为您提供:
p:nth-of-type(1) {
margin-left: calc( 100% / 1 );
}
p:nth-of-type(2) {
margin-left: calc( 100% / 2 );
}
p:nth-of-type(3) {
margin-left: calc( 100% / 3 );
}
同样,我们用来添加@for
循环的插件与@for
使用的插件相同,因此有关其语法的更多信息,请查看上一教程中的“循环”部分。
其他“ for”循环插件选项:
- Anton Yakushev撰写的postcss-for的叉子: https : //github.com/xori/postcss-for
postcss-for插件必须在postcss-simple-vars之前运行,这意味着无法使用变量来设置您希望@for
循环迭代的范围。
如果存在问题,则可以改用postcss-for插件的此fork ,而应在 postcss-simple-vars插件之后加载。
因为它在评估变量之后运行,所以您可以随意使用变量来设置要让@for
循环迭代的范围,如下所示:
@from: 1;
@count: 3;
@for $i from @from to @count {
p:nth-of-type($i) {
margin-left: calc( 100% / $i );
}
}
添加变量
我们将在预处理器中添加两种变量,这两种变量都非常方便。 第一种使用类似Sass的语法,第二种使用CSS定制属性的语法,也称为CSS变量。
使用的变量插件:
- 由Andrey Sitnik撰写的postcss-simple-vars: https : //github.com/postcss/postcss-simple-vars
- 埃里克·伊斯特伍德(Eric Eastwood)的postcss-css-variables: https : //github.com/MadLittleMods/postcss-css-variables
安装这两个插件,然后我们将一次测试每个插件。
首先,我们将测试postcss-simple-vars的类似Sass的语法。 打开您之前创建的“ _vars.css”文件,删除其内容并添加以下代码:
$default_padding: 1rem;
将以下内容添加到“ src / style.css”文件中并重新编译:
.post {
padding: $default_padding;
}
它应该编译为您提供:
.post {
padding: 1rem;
}
现在,我们将测试CSS自定义属性,例如postcss-css-variables的语法。 将以下代码添加到“ src / style.css”文件中:
:root {
--h1_font_size: 3rem;
}
h1 {
font-size: var(--h1_font_size);
}
@media ( max-width: 75rem ){
h1 {
--h1_font_size: 4vw;
}
}
它应编译为:
h1 {
font-size: 3rem;
}
@media ( max-width: 75rem ) {
h1 {
font-size: 4vw;
}
}
注意,使用CSS变量时,我们只需要在媒体查询中更改--h1_font_size
变量的值,它就会自动输出关联的font-size
属性。 这是特别有用的功能。
为什么要同时使用两种变量?
在继续之前,我将再次简单地提到,本教程中采用的方法不是您必须采用的方法。 如果您要使用一种变量而不是其他变量,那完全可以。
从我的角度来看,我喜欢同时使用两种变量的原因是我以两种不同的方式使用它们。 我通常会在主样式表中使用CSS定制属性语法,而在部分文件中使用类似Sass的变量。
如果/当跨浏览器很好地支持它们时,这可以让我为可能在实时项目中实际使用的变量类型设置CSS自定义属性。 如您在上面的示例中所见,它们还具有某些类似于Sass变量所没有的功能。
同时,对于不属于实时样式表的内容,我可以使用类似Sass的变量,尤其是那些纯粹存在的东西,可以通过诸如每个循环,条件和其他转换之类的东西进行处理。
其他变量插件选项:
- 乔纳森·尼尔(Jonathan Neal)的postcss-advanced-variables: https : //github.com/jonathantneal/postcss-advanced-variables
作为使用postcss-simple-vars的替代方法,您可能想考虑使用postcss-advanced-variables ,该插件用作PreCSS包的一部分。
这也是一个极好的选择,主要区别在于它可以在同一个插件中处理所有条件,循环和变量。 对我来说,我目前选择postcss-simple-vars的原因是我更喜欢条件来自单独的插件。 postcss-conditionals,我们将在稍后介绍。
- Maxime Thirouin的postcss-custom-properties: https : //github.com/postcss/postcss-custom-properties
您可能更喜欢postcss-custom-properties ,而不是使用postcss-css-variables。
两者之间的本质区别是postcss-custom-properties严格符合W3C的自定义属性规范,因此您可以确信自己仅编写了正确的将来CSS。 另一方面,postcss-css-variables提供了额外的功能,但是这样做并不能声称与规范完全相同。
我个人选择postcss-css-variables,因为我在预处理的上下文中使用了它,无论如何我都会写很多非规范代码。 因此,我宁愿添加的功能超过100%的规范合规性。
但是,如果在编写将来CSS时使用变量,则可能会发现postcss-custom-properties更适合您。
添加“每个”循环
使用的“每个”循环插件:
- 由Alexander Madyankin撰写的postcss-each: https : //github.com/outpunk/postcss-each
安装postcss-each插件,然后将此变量代码添加到“ _vars.css”文件中:
$social: twitter, facebook, youtube;
这段代码定义了一个列表,存储在$social
变量中。
现在,我们将创建一个@each
循环以迭代$social
变量中存储的值。 将此代码添加到您的“ src / style.css”文件中:
@each $icon in ($social){
.icon-$(icon) {
background: url('img/$(icon).png');
}
}
我们的@each
循环现在已经准备好了,但是在我们对其进行编译之前,我们需要对postcss-simple-vars的选项进行一些配置更改。
您会注意到,在上面的代码中,我们使用$icon
表示我们正在迭代的当前值。 由于postcss-simple-vars插件会寻找$
符号以识别变量,因此可能会出现一些困难。
这意味着它将看到$icon
,认为它是一个变量,尝试对其进行处理,然后看到它没有值。 这将使其停止编译并将发现未定义变量的错误记录到控制台。
为了解决这个问题,我们想在插件选项中添加silent: true
选项。 这意味着,如果发现未定义的变量,它将不会停止编译以记录错误,它将继续进行下去。 因此,它不会被@each
循环中的$icon
所困扰,并且我们将能够成功进行编译。
在Gulpfile或Gruntfile的处理器数组中,设置以下选项:
/* Gulpfile */
simple_vars({silent: true})
/* Gruntfile */
require('postcss-simple-vars')({silent: true})
现在编译您CSS,您应该得到:
.icon-twitter {
background: url('img/twitter.png');
}
.icon-facebook {
background: url('img/facebook.png');
}
.icon-youtube {
background: url('img/youtube.png');
}
其他“每个”循环插件选项:
- 乔纳森·尼尔(Jonathan Neal)的postcss-advanced-variables: https : //github.com/jonathantneal/postcss-advanced-variables
如前所述,postcss-advanced-variables是另一个出色的插件选项,可将变量,循环和条件全部集中处理。
添加条件
使用的条件插件:
- Andy Jansson撰写的postcss-conditionals: https : //github.com/andyjansson/postcss-conditionals
我之前提到过,此插件是我处理条件的首选。 这是因为我发现它能够处理更复杂的条件检查。 它包括对@else if
语法的支持,这意味着您可以在单个代码中针对更多条件进行测试。
安装postcss-conditionals插件后,通过将以下代码添加到您的“ src / style.css”文件中进行测试:
$column_count: 3;
.column {
@if $column_count == 3 {
width: 33%;
float: left;
} @else if $column_count == 2 {
width: 50%;
float: left;
} @else {
width: 100%;
}
}
这段代码将检查我们在变量@column_count
设置的值,并根据找到的内容输出不同的width和float值。 它的工作方式与之前的预处理教程中使用的代码相同,但是现在, @else if
行能够将要测试的条件数从两个增加到三个,我们就可以使用@else if
。
重新编译后,应该会给您:
.column {
width: 33%;
float: left
}
尝试将$column_count
更改$column_count
2
或1
然后再次编译以查看其如何更改CSS输出。
我们还可以在mixin内很好地使用这些类型的条件,我们之前已经为其提供了支持。 例如,我们可以创建一个mixin来生成列布局代码,如下所示:
@define-mixin columns $count {
@if $count == 3 {
width: 33%;
float: left;
} @else if $count == 2 {
width: 50%;
float: left;
} @else {
width: 100%;
}
}
.another_column {
@mixin columns 2;
}
这将为您提供输出:
.another_column {
width: 50%;
float: left;
}
其他条件选项:
- 乔纳森·尼尔(Jonathan Neal)的postcss-advanced-variables: https : //github.com/jonathantneal/postcss-advanced-variables
如前所述,postcss-advanced-variables是另一个出色的插件选项,可将变量,循环和条件全部集中处理。
为数学添加Calc()
使用的Calc()插件:
- Maxime Thirouin撰写的postcss-calc: https : //github.com/postcss/postcss-calc
在先前的教程中,我们通过cssnano使用postcss-calc来帮助使calc()
实例的使用效率更高。 但是,在预处理的情况下,无论我们希望在样式表中使用数学运算的任何地方,它都非常有用。
继续安装postcss-calc,然后通过使上面添加的列生成mixin更高效来对其进行测试。
现在,我们使用条件语句来检查混入的$count
参数被设置为1
, 2
或3
,然后输出一个预先计算相应的宽度。 取而代之的是,无论通过mixin传递多少数字,我们都将使用calc()
为列代码自动输出正确的宽度。
添加到您的“ src / style.css”文件中:
@define-mixin columns_calc $count {
width: calc( 100% / $count );
@if $count > 1 {
float: left;
}
}
.column_calculated {
@mixin columns_calc 2;
}
现在,我们可以即时计算它,而不是对某些列数所需的百分比宽度进行硬编码。
postcss-calc插件将转换width: calc( 100% / $count );
根据我们调用mixin时传递的值,将其转换为静态量,在这种情况下为2
。
重新编译代码,您应该看到以下输出:
.column_calculated {
width: 50%;
float: left;
}
注意 :只要postcss-calc可以将calc()
解析为静态值,它将输出到您的代码中。 如果不能,它将保持不变,因此您仍然可以对运行时需要浏览器处理的值使用calc()
。
添加嵌套
使用的嵌套插件:
- 由Andrey Sitnik嵌套的postcss: https : //github.com/postcss/postcss-nested
对于嵌套,我们使用与PreCSS包中使用的插件相同的插件,因此您可以参考上一教程以获得有关语法的完整信息。
安装postcss-nested,然后通过编译以下代码来测试一切是否正常:
.menu {
width: 100%;
a {
text-decoration: none;
}
}
生成CSS应该是:
.menu {
width: 100%;
}
.menu a {
text-decoration: none;
}
添加扩展
扩展使用的插件:
- 乔纳森·尼尔(Jonathan Neal)发布的postcss-sass-extend: https : //github.com/jonathantneal/postcss-sass-extend
对于扩展,我们将使用postcss-sass-extend插件。 与我们之前使用PreCSS的教程中介绍的语法相比,它将为我们提供不同的语法使用。 不是使用@define-extend extend_name {...}
使用%extend_name {...}
@define-extend extend_name {...}
。
它们仍然与@extend %extend_name;
语法基本相同@extend %extend_name;
。
请注意,postcss-sass-extend插件实际上确实与PreCSS一起提供,但是我认为默认情况下不会加载它,因为当我尝试使用未编译的必需语法时。
将postcss-sass-extend安装到您的项目中之后,请使用以下代码对其进行测试:
%rounded_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}
.blue_button {
@extend %rounded_button;
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
@extend %rounded_button;
border-color: #C41A1E;
background-color: #FF2025;
}
它应编译为:
.blue_button, .red_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}
.blue_button {
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
border-color: #C41A1E;
background-color: #FF2025;
}
其他扩展插件选项:
- postcss-extend: https : //github.com/travco/postcss-extend
- postcss-simple-extend: https : //github.com/davidtheclark/postcss-simple-extend
附加功能
到目前为止,我们已经介绍了大多数预处理器共有的核心功能。 但是,仍然有更多的插件可以提供额外的功能。 其中一些功能可以在其他预处理器中找到,而某些功能则必须去PostCSS才能找到。 现在,我们将简要介绍这些额外的选项。
色彩处理
外挂程式:
- Maxime Thirouin的postcss-color-function: https : //github.com/postcss/postcss-color-function
- Ivan Vlasenko撰写的postcss-color-alpha: https : //github.com/avanes/postcss-color-alpha
- 克里斯托弗·约瑟夫(Kristofer Joseph)的postcss-color-scale: https : //github.com/kristoferjoseph/postcss-color-scale
调整颜色的能力可能是预处理器中最有用的功能之一。 实际上,有几个PostCSS彩色插件,但其中三个在预处理设置中特别适合在家中使用。 它们允许进行各种颜色转换,包括变亮,变暗,饱和,添加alpha值等等。
属性定义
插入:
- Dale Eidd的postcss-define-property: https : //github.com/daleeidd/postcss-define-property
可以将该插件提供的功能与Stylus的无缝mixins进行比较,从而@mixin
使用@mixin
类的语法,而是以如下@mixin
定义代码块,以便它们随后可以与本地财产,例如
/* Define a property */
size: $size {
height: $size;
width: $size;
}
/* Use it like a native property */
.square {
size: 50px;
}
该插件还可用于重新定义本机属性,以满足您的需求。
属性查询
插入:
- Simon Smith的postcss-property-lookup: https : //github.com/simonsmith/postcss-property-lookup
属性查找是Stylus中的一项功能,非常方便。 它允许您从相同样式中查找属性的值。 例如,您可以设置一个右边距以匹配左边margin-left: 20px; margin-right: @margin-left;
:margin-left: 20px; margin-right: @margin-left;
margin-left: 20px; margin-right: @margin-left;
嵌套属性
插入:
- 杰德·毛(Jed Mao)的postcss-nested-props: https : //github.com/jedmao/postcss-nested-props
虽然我们在上面介绍的常规嵌套打开了包装选择器,但postcss-nested-props插件打开了嵌套属性,例如:
/* Origincal code */
.element {
border: {
width: 1px;
style: solid;
color: #ccc;
}
}
/* After processing */
.element {
border-width: 1px;
border-style: solid;
border-color: #ccc;
}
匹配
插入:
- 曹瑞恩的postcss-match: https : //github.com/rtsao/postcss-match
匹配为您提供了另一种执行条件检查的方式,这次使用Rust,例如模式匹配,类似于JavaScript或PHP中的switch语句。 与编写许多@if else
检查相比,这可以为您提供一种更有效的方法来检查多个条件。
CSS Sprite生成
插入:
- Viktor Vasilev撰写的postcss-sprites: https : //github.com/2createStudio/postcss-sprites
CSS Sprite生成(Compass中的一个流行功能)也可以通过postcss-sprites插件来完成。 该插件将扫描您CSS中的图像,将这些图像合并到一个Sprite表中,并根据需要更新您的代码,以便正确地从新Sprite表中显示。
还有更多选择
当前有一个非常强大的语言扩展插件列表可供选择,超出了我们在此处可以覆盖的范围,因此请在以下位置查看完整列表: https : //github.com/postcss/postcss#language-extensions
即将推出:替代语法
对于许多人来说,以简洁高效的语法(通常是无分号和花括号)书写的能力是预处理器(如Stylus或Sass)的一大吸引力。 新发布的PostCSS 5.0版现在支持自定义解析器,这将支持新语法。 SugarSS将成为简洁的语法分析器,目前正在讨论如何构造该语法。
您可以随时添加自己的
PostCSS仍然是相对较新的,您可能会发现需要使用自定义预处理器实现一些功能,而目前没有此插件。 这个模块化生态系统的优点在于,您可以选择通过创建自己的插件自行解决该问题。 任何人都可以做到,并且进入的障碍比您尝试将自己的功能添加到Stylus,Sass或LESS时要低得多。 我们将在以后的教程中学习如何操作。
在下一个教程中
如果要使用PostCSS,则不必在PreCSS和滚动自己的预处理器之间进行选择。 如果您愿意,实际上您可以完全不选择任何基于PostCSS的预处理,而是与您喜欢的预处理器并列使用。
在下一个教程中,我们将学习如何将StCSS与Stylus,Sass或LESS结合使用。 到时候那里见!
翻译自: https://webdesign.tutsplus.com/tutorials/postcss-deep-dive-roll-your-own-preprocessor--cms-24584
postcss插件开发