PostCSS使用速记

发布时间:2023-10-13 17:24
最后更新:2023-12-22 15:49
所属分类:
前端 CSS

PostCSS 是一个使用 Javascript 来处理 CSS 的工具库。我们通常会在许多 UI 框架中看到它的身影,习惯于使用 SASS、LESS 等 CSS 预处理器的我们,可能第一眼会觉得这是不是一个新的预处理器。但是事实是,PostCSS 是一个用于转换 CSS 语法的工具。CSS 文件经过 PostCSS 中多种插件的处理以后,就会形成全新的 CSS 内容。

但是 PostCSS 能够完成的事情并不只是对 CSS 的内容进行转换,其实还包括了对 CSS 内容的检查、压缩、优化以及一些内容的生成等。在使用 PostCSS 之前,需要了解 PostCSS 存在以下特征。

  1. PostCSS 是由众多的插件实现 CSS 处理功能的,其处理方式类似于 CSS 预处理器,但是 PostCSS 并不是预处理器或者后处理器。
  2. PostCSS 并没有引入新的语法或者未来 CSS 的语法。
  3. PostCSS 本身没有提供整理或者优化 CSS 的工具。
  4. 相比其他的 CSS 预处理器提供了更高的性能。
  5. 既支持正常的 CSS,也支持结合 LESS 或者 SASS 等预处理器语法。

在项目中配置使用 PostCSS

PostCSS 在项目中一般是结合自动化构建工具使用,所以要在项目中使用 PostCSS ,只需要在项目中安装 PostCSS 即可,比如直接执行命令:npm install --save-dev postcss

但是在项目仅仅安装 PostCSS 是没有什么效果的,所以还需要安装一些插件,例如安装著名的 Autoprefixer:npm install --save-dev autoprefixer。正常来说使用 PostCSS 来处理 CSS 文件是需要预先安装 PostCSS 命令行工具的,但是在大部分情况下我们都还是使用构建工具的,所以这里只记录如何配合构建工具使用。

配合构建工具使用时,首先就需要先编写一个 PostCSS 的配置文件,这个文件一般都会放置在项目根目录中,与 package.json 放置在一起。PostCSS 的配置文件名约定为 postcss.config.js

例如这个安装了 Autoprefixer 的项目里,postcss.config.js 的内容就是下面这样的:

1
2
3
4
5
6
7
8
module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-preset-env': {
      stage: 0,
    },
  }
};

或者可以使用列表来初始化 plugins 字段。

1
2
3
4
5
6
7
8
module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-preset-env')({
      stage: 0
    }),
  ]
};

但是需要注意的是,使用列表来初始化 plugins 字段的时候,会经常被报出 require is not defined 错误,虽然这个错误是可以被安全的忽略的,但是这里报错的红线一定可以逼死强迫症的,所以建议还是采用对象来初始化 plugins 字段的方法。使用这种配置方法可以将 PostCSS 的插件包名作为对象的键,插件的配置作为这个键的值。

如果项目使用的是 Vite 作为构建工具,那么 PostCSS 配置到这里就已经可以正常使用了。如果使用的是 Webpack,那么就还需要继续在 Webpack 的配置中配置 postcss-loader。因为 PostCSS 可以处理包括 SASS、LESS 等 CSS 预处理器类型的文件,所以对于项目里使用了 CSS 预处理器的也需要单独进行配置。postcss-loader 是对于 CSS 的处理,所以需要放置在 css-loader 的后面。

Webpack 中 Loader 的声明顺序和 Loader 的应用顺序是相反的,后声明的 Loader 会更优先的被使用。所以 postcss-loader 需要写在最靠近 CSS 源码的位置上,也就是 CSS Loader 配置中的最后一位。如果使用了其他的 CSS 预处理器,那么 PostCSS Loader 需要放在 CSS 预处理器的 Loader 前面。

如果是使用Vite通过postcss.config.js来配置使用PostCSS,那么各个插件的应用顺序就是按照其列举在配置文件中的顺序使用。所以在编排插件列表的时候需要注意其使用顺序,越靠后的插件越会覆盖之前插件的配置和运行结果。

例如配置处理 CSS 文件和 SCSS 文件的示例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
module.exports = {
  modules: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
              config: {
                path: 'postcss.config.js',
              }
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
              config: {
                path: 'postcss.config.js',
              }
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            }
          }
        ]
      }
    ],
  }
}

常见 PostCSS 插件的使用

如果只是在项目中配置了 PostCSS,但是没有安装和配置插件,那么 PostCSS 的威力是无法发挥出来的。所书写的 CSS 也依旧是原来 CSS 的样子,不会得到 PostCSS 的任何辅助。浏览 PostCSS 的网站你会发现 PostCSS 拥有众多的插件,这里值拣选其中使用的比较多的几个做进一步的说明和记录。

PostCSS 建议所有的插件都是以 postcss- 开头,但这也只是建议,希望开发者遵守。基本上所有的 PostCSS 插件都是以 --save-dev 参数安装在 package.json 中的 devDependencies 中的。

autoprefixer

autoprefixer 插件允许使用来自 Can I Use 的值来自动扩充 CSS 字段名称。例如我们常常会见到 CSS 属性 transition-webkit-transition 的形式出现,这种形式就是不同的浏览器厂商针对特定的 CSS 字段提供的特殊支持。

在 CSS 中使用这种浏览器厂商提供的扩展 CSS 字段属性或者 CSS 功能,是十分不方便的,它本身就是用来使指定浏览器兼容通用 CSS 定义的,但是因为浏览器的不同,同一个 CSS 属性就需要开发人员反复使用不同的浏览器厂商扩展定义定义相同的 CSS 效果。

自动扩展 CSS 属性和值的浏览器厂商扩展定义,简化开发人员对于 CSS 的编写就是 autoprefixer 插件的主要功能了。例如有以下这个简单的 CSS 定义。

1
2
3
4
.example {
  display: grid;
  transition: all .5s;
}

在经过 autoprefixer 的处理以后,就会变成下面的样子。

1
2
3
4
5
6
7
.example {
  display: -ms-grid;
  display: grid;
  -webkit-transition: all .5s;
  -o-transition: all .5s;
  transition: all .5s;
}

autoprefixer 没有什么需要配置的,需要使用的时候直接在 postcss.config.jsplugins 字段中列出即可。

postcss-preset-env

postcss-preset-env 插件允许你在 CSS 中使用更新的 CSS 特性,它会自动将这些新的 CSS 特性转换为浏览器可以理解的内容,并且会自动添加 CSS 渲染时所需的 ployfill

postcss-preset-env 中的功能已经包含了 autoprefixer 的功能,所以这两个插件择一使用即可,虽然很多时候可能还是会同时使用它们。

autoprefixer 不同,postcss-preset-env 提供了众多的参数可供配置,其中比较常用的如下。

  • stage: 指示启用哪些 CSS 特性,默认值为 2。可取值 0 (实验性功能)至 4 (稳定功能)。
  • minimumVendorImplementations: 使用哪一级别的浏览器供应商 polyfill,默认值为 0。 可取值 0 (无供应商提供)至 3 (所有供应商都提供)。
  • features: 允许使用 polyfill 中的哪些特性,特性可以从特性列表中查询。可取值为
    • true:全部允许;
    • false:全部不允许;
    • 详细特性列表。
  • env:指定适配在 browserslist 中定义的环境变量。
  • browsers:指定适配哪些浏览器的版本,将会覆盖 browserslist 中的配置。
  • insertBefore:允许在当前插件之前加入其他的插件。
  • inserAfter:允许在当前插件之后加入其他的插件。
  • autoprefixer:允许传递额外的参数给 autoprefixer。传递 false 将禁用 autoprefixer
  • preserve:指示其他插件是否应该收到 preserve 选项。
  • debug:是否启用调试信息的输出。

postcss-use

postcss-use 允许在 CSS 中直接启用 PostCSS 的插件。例如可以在样式文件中这样写。

1
@use postcss-preset-env(stage: 0, browsers: "last 2 versions");

这样就可以在样式文件中动态的启用插件。

postcss-import

postcss-import允许PostCSS直接导入本地样式文件、位于node😌modules中的样式文件或者是Web Module中的样式文件。在使用本插件以后,可以直接在@import语句中使用本地路径、NodeJS模块路径或者HTTP URL来指定需要导入的文件。

postcss-modules

postcss-module 允许项目中在任何位置都可以使用 CSS Modules 的样式隔离概念。postcss-module 对于 CSS Module 的建立是自动的。

postcss-autoresetpostcss-initial

postcss-autoreset 是一个用于设定全局样式重置的插件。其常用的配置项是 reset,这个配置项的值是一个对象,可以用来定义 marginpaddingborderRadius 等内容的默认尺寸。

postcss-initial 是一个用来与 postcss-reset 搭配使用的插件,可以回退 initial 关键字。

postcss-custom-properties

postcss-custom-properties允许在任意CSS声明块中定义变量(CSS Variables)。如同CSS标准所描述的那样,CSS Variables在定义的时候以自定义样式属性的形式出现,并使用--开头。CSS Variables在使用的时候需要使用var(),来引用其指代的值。

例如:

1
2
3
4
5
6
7
:root {
  --spacing-md: 0.5rem;
}

.paragragh {
  line-height: calc(var(--spacing-md) * 3);
}

在不同级别的块中,相同名称的变量是被允许存在的,但是后定义的变量将在其作用域内覆盖掉之前定义的同名变量的值,或者也可以称为后定义的变量遮蔽了之前定义的变量的值。

你可能还注意到了另一个插件postcss-css-variables,这个插件虽然声称支持 CSS Custom Properties (CSS Variables),但是在许多情况下的实测,其效果远不如postcss-custom-properties插件,尤其是在配合postcss-import等插件提供的导入功能时。

postcss-simple-vars

postcss-simple-vars 插件提供了一种允许像 SASS 语法中那样定义变量的功能。postcss-simple-vars 插件允许使用 $variable 的形式在 CSS 文件中定义变量,然后可以在样式文件的任意部位使用,使用的方式与 SASS 语法基本一致。

除了可以直接在 CSS 文件中定义变量以外,postcss-simple-vars 插件还支持在 PostCSS 配置中定义变量,在配置文件中定义的变量将在 PostCSS 处理的所有 CSS 文件中起效。

postcss-simple-vars 插件常用的配置选项有:

  • variables,定义全局可以使用的变量。这里定义的变量不需要使用前缀的 $
  • onVariables,当所有样式文件中使用的变量都是已知的时将会调用的回调。
  • unknown,当所有样式问存在未知变量的时候将会调用的回调。
  • slient,对于所有样式文件存在未知变量时,是否不报错误。默认为 false,需要报错。
  • only,设定插件仅提供已有的变量,其他的变量将会保持原样。

precss

precss 插件提供了一套类似于 SASS 的 CSS 语法功能。其中比如变量、条件判断、循环等。例如在引入 precss 插件以后,CSS 里就可以这样来书写。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$blue: #0000bb;
$columnWidth: 150px;

.main_content {
  width: calc(2 * $columnWidth);
}

.menu_link {
  background: $blue;
}

postcss-utilities

postcss-utilities 插件提供了一整套的 CSS 工具功能,包括 Mixin、快捷方法、辅助函数等。例如以下示例:

1
2
3
.margin-4 {
  @util margin(40px 20px 40px null);
}

就会被转换为:

1
2
3
4
5
.margin-4 {
  margin-top: 40px;
  margin-right: 20px;
  margin-bottom: 40px;
}

以下是 postcss-utilities 提供的常用工具函数列表。

  • @util aspect-ratio([ratio]),可以固定设定一个元素的长宽比,参数中的长宽比使用 int:int 的格式,例如: @util aspect-ratio(16:9);
  • @util border-color([colors]),设定四个边框的颜色,四个颜色使用空格分隔列出,没有颜色的使用 null 表示。
  • @util border-top-radius([radius]),设定元素上部两个圆角。相似的功能还有 border-right-radiusborder-bottom-radiusborder-left-radius
  • @util border-style([styles]),设定元素四个边框的样式,使用空格分隔。
  • @util border-width([sizes]),设定元素四个边框的宽度,使用空格分隔。
  • @util center,使用绝对定位将元素固定在父级元素的中央位置。在插件配置中增加 {centerMethod: 'flexbox'} 可以改为使用 Flexbox 布局方式进行定位,但是此时 @util center 需要使用在父级元素上。
  • @util center-block,将一个元素在父级元素中利用宽度进行居中。
  • @util circle([radio], [color]),绘制一个圆形。
  • @util clearfix,增加清除浮动的代码。在插件配置中增加 {ie8: true} 可以使这个功能兼容 IE8 。
  • @util hd([min-resoluton]) { 嵌套样式 },定义媒体查询。
  • @util hide-visually,设定内容仅供屏幕阅读器使用,内容不在屏幕上展示。
  • @util hr([color], [vertical-margin], [style], [height]),设定水平线的样式。
  • @util margin([sizes]),快速定义元素的 margin 留白。
  • @util padding([sizes]),快速定义元素的 padding 内边距。
  • @util no-hover { 嵌套样式 },为不支持 hover 的设备和移动端设备增加禁用 hover 的样式,需要在 html 标签上增加 .no-hover 样式类。
  • @util no-js { 嵌套样式 },与 no-hover 类似,增加不支持 Javascript 样式。
  • @util position([position], [lengths]),设定元素的定位属性,其中 position 参数为定位方式。
  • @util reset-list,清除列表元素的默认样式。
  • @util reset-text,清除文本元素的默认样式。
  • @util size([width], [height]),设定元素的宽和高,宽默认为 auto,高默认与宽的值一致。
  • @util sticky-footer([height]),设定固定在页面底部的页脚样式,主要设定其高度。
  • @util text-hide,隐藏元素中的文字。
  • @util text-stroke([size], [color], [smooth]),为元素增加一条文本删除线。
  • @util triangle([size], [color], [orientation]),绘制一个三角形。
  • @util truncate,设定单行文本的截断。
  • @util truncate([lines], [line-height]),设定多行文本的截断。
  • @util word-wrap([wrap]),设定元素中文字的自动换行。

short

short 提供了众多 CSS 样式属性的简写,可以比较有效的提速 CSS 的编写。

使用 short 插件以后,可以选择不使用 postcss-utilities 插件,两者的功能在一定程度上是重复的。

short 插件所提供的简写样式属性主要有一以下这些。

  • size,同时设定元素的宽和高。
  • margin,同时设定元素的留白。
  • padding,同时设定元素的内边距。
  • position,快速设定元素的定位属性。
  • color,同时设定元素的 colorbackground-color 属性,color 值在前。
  • overflow,快速分别设置 xy 轴上的溢出控制。
  • border,快速定义元素的四个边框样式,不同类型的样式值之间使用 / 分隔。
  • border-radius,使用逆时针语法快速定义元素的四个圆角。
  • font-size,同时定义字体的大小和行高,字体大小和行高之间使用 / 分隔。
  • font-weight,使用普通名称定义字体粗细。

cssnano

cssnano 插件提供的功能主要是 CSS 压缩功能。除了 CSS 压缩功能,cssnano 还提供了其他一系列的优化功能,这些可以通过配置来设定使用。

postcss-nested

postcss-nested 插件可以提供类似于 SCSS 与 LESS 等 CSS 预处理器中提供的嵌套定义样式的语法格式。

与 SCSS 等 CSS 预处理器一样,postcss-nested 也是使用 & 符号来代替其父级样式名称。

postcss.config.js 配置文件中配置 postcss-nested 插件的使用,需要尽可能将其配置到比较靠前的位置。

如果不需要使用 SCSS 或者 LESS 等预处理器提供的除嵌套样式定义等功能,那么就完全可以使用 postcss-nested 插件来代替后面提到的 postcss-scss 或者 postcss-less 等语法解析插件。

另外,根据目前 CSS 技术规范的发展,有不少预处理器中提供的功能都已经被合并进了 CSS 技术规范中,这些功能可以通过 postcss-preset-env 插件中的 features 配置启用。此时就不再需要 postcss-nested 等专用功能的插件了。

postcss-color-mod-function

这个插件提供了一系列用于计算和操作颜色的函数。这个插件主要使用color-mod()函数来提供颜色变换的功能。

color-mod()函数已经被从 CSS Color Module Level 4 标准草案中被移除了。
postcss-color-function插件可以实现与postcss-color-mod-function基本相同的功能,但是这里更加推荐使用postcss-color-mod-function,因为这个插件更新一些。

使用color-mod()进行颜色变换的时候,调用格式为color-mod([HEX颜色|RGB颜色|HUE颜色] 颜色调整函数)。颜色调整函数主要有以下这些。

  • red([+ | -]? [number|percentage]),调整红色数量或者比例。
  • green([+ | -]? [number|percentage]),调整绿色数量或者比例。
  • blur([+ | -]? [number|percentage]),调整蓝色数量或者比例。
  • a([+ | -]? [number|percentage]),调整透明度数量或者比例。
  • red(* percentage),调整红色比例。
  • green(* percentage),调整绿色比例。
  • blue(* percentage),调整蓝色比例。
  • a(* percentage),调整透明度比例。
  • [hue|h]([+ | - | *]? angle),调整HUE色相角度。
  • [saturation|s]([+ | - | *]? percentage),调整饱和度比例。
  • [lightness|l]([+ | - | *]? percentage),调整亮度比例。
  • [whiteness|w]([+ | - | *]? percentage),调整变白比例。
  • [blackness|b]([+ | - | *]? percentage),调整变黑比例。
  • tint(percentage),按比例变浅。
  • shade(percentage),按比例变深。
  • blend(color percentage [rgb|hsl|hwb]?),按照指定的颜色模式和比例与指定颜色进行混合。
  • contrast(percentage),调整对比度比例。

lost

lost 插件提供了一个强大的 Grid 布局系统,它通过一系列的 CSS 样式属性来定义 Grid 布局。因为 Grid 布局系统需要父级容器元素和 Grid 列容器元素共同参与定义,所以下面这些 CSS 样式属性将指明其应该使用在哪一级元素上。

  • lost-align,应用在父级容器上,用于设定嵌套元素的对齐。可以设定两个值,分别对应定位和是否使用 Flexbox 布局。
    • resethorizontalverticaltop-lefttop-centertoptop-rightmiddle-leftleftmiddle-centercentermiddle-rightrightbottom-leftbottombottom-right
    • flex 或者 no-flex
  • lost-center,应用在父级容器上,用于将容器元素居中并同时设定其内边距。可以设置三个值,分别是最大宽度、内边距和是否使用 Flexbox 布局。
  • lost-column,应用在子级容器上,用于定义子级容器的宽度。可以设置四个值,分别是元素宽度、最右侧元素的右边距、所有元素的间距、是否使用 Flexbox 布局。
    • 元素宽度是用一个分数定义,表示将父级容器划分为几栏。
  • lost-flex-container,应用于父级容器上,设定 Flexbox 布局中子级元素的排列方向。
  • lost-masonry-column,应用于子级元素,设定子级元素的宽度。可设定的值可参考 lost-column
  • lost-masonry-wrap,应用于父级元素,设定子级元素的换行。可以设置两个值,分别为是否使用 Flexbox 布局和子级元素之间的间隔。
  • lost-move,应用于子级元素,设定子级元素的排序。可以设定三个值,分别为移动的栏数、移动的方向和是否使用 Flexbox 布局。
    • 移动的栏数同样使用分数表示。
    • 移动的方向取值为 rowcolumn
  • lost-offset,应用于子级元素,设定子级元素的位移。可以设定四个值,前三个值与 lost-move 相同,最后一个值用于设定浮动的清除,可取值如下。
    • clearclear-leftclear-rightclear-topclear-bottom
  • lost-row,应用于子级元素,设定子级元素的行高和间隔。可以设定三个值,分别为行高、间隔和是否使用 Flexbox 布局。
  • lost-unit,应用于父级元素,设定 Grid 系统索要使用的单位,可以取 vhvw%,默认为 %
  • lost-utility,可以应用于父级元素或者子级元素,主要功能是利用 Mixin 为元素增加一些特效。
    • edit,可以增加一层半透明遮罩。
    • edit rgb(r,g,b),增加一层指定颜色的半透明遮罩。
    • edit rgba(r,g,b,a),增加一层指定颜色和指定透明度的遮罩。
    • edit #000000,增加一层指定颜色的半透明遮罩。
    • edit #00000000,增加一层指定颜色指定透明度的遮罩。
    • clearfix,增加清除浮动的 Mixin。
    • overlay [max-width] [columns] [gutter] [color],增加一层可以遮罩整个 Grid 的遮罩。
  • lost-waffle,应用于子级元素,用于创建一个宽高都是容器宽高比例并且右侧和底部都到右指定宽度间隔的块。可以设定五个值,分别为宽高比例、最右侧元素的边距、间隔宽度、是否使用 Flexbox 布局和最右侧元素是否使用向右侧浮动。

此外,lost 还提供了一个 lost-vars 函数可以用来获取当前布局样式中的间隔尺寸,例如 gutter-local 可以用来获取当前 Grid 布局中的间隔尺寸。

postcss-syntax

postcss-syntax 插件提供了按照样式文件的后缀支持来自不同 CSS 预处理器样式文件的功能。根据项目里所使用的 CSS 预处理器,需要搭配安装其他相应的解析插件。以下是不同 CSS 文件类型与需要安装的 PostCSS 语法解析插件之间的关系。

样式文件类型 需要安装的 PostCSS 插件
SCSS postcss-scss
SASS postcss-sass
LESS postcss-less
SugarSS sugarss
CSS-in-JS postcss-jsx
HTML postcss-html
Markdown postcss-markdown

语法类插件

语法类插件的主要作用是扩展 CSS 的语法解析能力,大多数情况下都用来让 PostCSS 支持 CSS 预处理器。语法类插件的使用不在 plugins 字段中配置,而是在 syntax 字段中配置。以下是一个使用 postcss-scss 支持 SCSS 编写样式文件的示例。

1
2
3
4
5
6
module.exports = {
  syntax: 'postcss-scss'.
  plugins: {
    // ...
  }
}
这里可以使用的语法类插件就是上一节中 postcss-syntax 插件支持的那些解析插件,如果不使用 postcss-syntax 插件,那么就直接安装语法类插件,配置后使用即可。

一个项目中常用的插件组合

其实我们在选择使用PostCSS插件的时候,经常会遇到一个问题,那就是我们所需要的功能,常常有很多插件都同时提供了,还有一些情况下,一个插件可能同时包含了其他几个插件的功能,又或者我们常用的插件已经不不再维护了需要更换成一个新版的插件。

这里给出一个推荐使用的插件列表,同时会提示你这个插件里都包含了其他的哪些插件,或者可以替代哪些插件,防止重复安装。

  • postcss-custom-properties
  • postcss-import
  • postcss-preset-env,如果使用了precss,那么可以不显式安装这个。
    • 包含autoprefixer
  • postcss-color-mod-function,这个插件的主要用途是计算和保证所有的颜色定义都是可以直接被其他CSS定义使用的。
  • postcss-utilities,这个插件的主要工作是完成内置定义的Mixin的展开,所以需要其中所使用的内容较为固定。
  • lost,将lost插件放置在比较靠后的位置可以保证其能够使用之前其他插件转换生成的内容。
  • precss,因为这个插件会完成众多功能的转换,并且可能需要使用到之前其他插件转换的结果,所以要尽可能的放置在靠后的位置。
    • 包含postcss-extend-rulepostcss-advanced-variablespostcss-preset-envpostcss-atrootpostcss-property-lookuppostcss-nested
  • cssnano,这个插件的主要功能是精简和压缩已经转换好的CSS定义内容,所以需要将其放置在整个处理流程的末尾。

推荐按照这个列表中的插件顺序在postcss.config.js中配置各个插件。


索引标签
前端
CSS
PostCSS