Web开发人员喜欢Sass CSS预处理程序。每一个开发人员都知道它是什么,89%经常使用它,而88%的高满意度。
许多Web捆绑程序都包含Sass处理,但是您可能在使用PostCSS时也没有意识到这一点。PostCSS主要以其Autoprefixer插件,其自动添加-webkit
,-moz
和-ms
在需要时供应商前缀的CSS特性。它的插件系统意味着它可以做更多的事情,例如.scss
无需使用Sass编译器即可编译文件。
本教程说明了如何创建自定义CSS预处理器,该预处理器可编译Sass语法并对其进行补充以提供更多功能。对于有特定CSS要求并且只懂一点Node.js的人来说,它是理想的选择。
快速开始
可以从GitHub克隆一个示例PostCSS项目。它需要Node.js,因此请运行npm install
以获取所有依赖项。
编译演示src/scss/main.scss
源代码以build/css/main.css
使用:
npm run css:dev
每当使用以下命令更改文件时,自动编译:
npm run css:watch
然后按Ctrl|退出观看 Cmd+C在终端中。
这两个选项还在处创建了一个源映射build/css/main.css.map
,该映射引用了开发人员工具中的原始源文件。
没有源映射的生产级最小化CSS可以使用以下命令进行编译:
npm run css:build
README.md
有关更多信息,请参考文件。
您应该用PostCSS代替Sass吗?
Sass编译器没有任何问题,但请考虑以下因素。
模块依赖
可以使用Node.jsnpm
软件包管理器在全球范围内安装Sass的最新Dart版本:
npm install -g sass
使用以下命令编译Sass.scss
代码:
sass [input.scss] [output.css]
源映射是自动生成的(--no-source-map
将其关闭),或者--watch
可以在更改时将其添加到自动编译的源文件中。
最新版本的Sass需要少于5MB的安装空间。
PostCSS应该需要更少的资源,并且需要一个具有自动前缀的类似Sass的基本编译器,而压缩需要不到1MB的空间。实际上,您的node_modules
文件夹将扩展到60MB以上,并随着添加更多插件而迅速增加。这主要是npm
安装其他依赖项。即使PostCSS可能不使用它们,也不能将其视为轻量级替代方案。
但是,如果您已经将PostCSS用于自动前缀或其他用途,则可能不需要Sass。
处理速度
慢速的基于Ruby的Sass编译器早已消失,最新版本使用已编译的Dart运行时。它很快。
PostCSS是纯JavaScript,尽管基准会有所不同,但编译同一源代码的速度可能会慢三倍。
但是,如果您已经在Sass之后运行PostCSS,则这种速度差异将不太明显。两步过程可能比单独使用PostCSS慢,因为它的许多工作都涉及标记CSS属性。
客制化
Sass语言包含大量功能,包括变量,嵌套,部分,混合和更多功能。有缺点:
-
您无法轻松添加新功能。
也许您想要将HSLA颜色转换为RGB的选项。可能可以编写自定义函数,但是其他要求将是不可能的,例如将SVG内联为背景图像。
-
您不能轻易限制功能集。
也许您希望您的团队不要使用嵌套或
@extend
。整理规则会有所帮助,但不会停止Sass编译有效.scss
文件。
PostCSS的可配置性更高。
PostCSS本身不执行任何操作。处理功能需要众多可用插件中的一个或多个。大多数执行单个任务,因此,如果您不想嵌套,请不要添加嵌套插件。如有必要,您可以在可以利用Node.js功能的标准JavaScript模块中编写自己的插件。
安装PostCSS
PostCSS可以与webpack,Parcel,Gulp.js和其他构建工具一起使用,但是本教程显示了如何从命令行运行它。
如有必要,请使用初始化一个新的Node.js项目npm init
。通过安装以下用于基本.scss
解析的模块来设置PostCSS,这些模块带有用于部分,变量,mixin,嵌套和自动前缀的插件:
npm install --save-dev postcss postcss-cli postcss-scss postcss-advanced-variables postcss-nested autoprefixer
与示例项目一样,PostCSS及其插件在本地安装。如果您的项目可能具有不同的编译要求,则这是一个实际的选择。
注意:PostCSS只能从JavaScript文件运行,但是该postcss-cli
模块提供了可从命令行调用的包装器。该postcss-SCSS模块允许PostCSS读取.scss
文件,但不改变它们。
自动前缀配置 {#autoprefixerconfiguration}
Autoprefixer使用浏览器列表根据支持的浏览器列表确定需要哪些供应商前缀。将此清单定义为中的"browserslist"
数组是最简单的package.json
。以下示例添加了供应商前缀,其中任何浏览器均具有至少2%的市场份额:
"browserslist": [
"> 2%"],
您的第一个版本
通常,您将只有一个根Sass.scss
文件,该文件可导入所有必需的部分/组件文件。例如:
// root Sass file// src/scss/main.scss@import '_variables';@import '_reset';@import 'components/_card';// etc.
可以通过运行npx postcss
,输入文件,--output
文件和所有必需的选项来启动编译。例如:
npx postcss ./src/scss/main.scss \
--output ./build/css/main.css \
--env development \
--map \
--verbose \
--parser postcss-scss \
--use postcss-advanced-variables postcss-nested autoprefixer
该命令:
-
解析
./src/scss/main.scss
-
输出到
./build/css/main.css
-
将
NODE_ENV
环境变量设置为development
-
输出外部源映射文件
-
设置详细的输出和错误消息
-
设置
postcss-scss
Sass解析器,并 -
使用插件
postcss-advanced-variables
,postcss-nested
以及autoprefixer
处理谐音,变量,混入,嵌套,和自动前缀
(可选)您可以在修改文件后添加--watch
到自动编译.scss
。
创建一个PostCSS配置文件
对于较长的插件列表,命令行很快变得难以处理。您可以将其定义为npm
脚本,但是PostCSS配置文件是一个更简单的选项,它提供了更多的可能性。
PostCSS配置文件是命名为JavaScript模块的文件postcss.config.js
,通常存储在项目的根目录(或运行PostCSS的目录)中。该模块必须export
具有一个功能:
// postcss.config.jsmodule.exports = cfg => {
// ... configuration ...};
它传递了一个cfg
具有postcss
命令设置属性的对象。例如:
{
cwd: '/home/name/postcss-demo',
env: 'development',
options: {
map: undefined,
parser: undefined,
syntax: undefined,
stringifier: undefined
},
file: {
dirname: '/home/name/postcss-demo/src/scss',
basename: 'main.scss',
extname: '.scss'
}}
您可以检查这些属性并做出相应的反应-例如,确定您是否在development
模式下运行并处理.scss
输入文件:
// postcss.config.jsmodule.exports = cfg => {
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
// ... configuration ...};
该函数必须返回一个属性名称与postcss-cli
命令行选项匹配的对象。以下配置文件复制了上面使用的long quick start命令:
// postcss.config.jsmodule.exports = cfg => {
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')(),
require('postcss-nested')(),
require('autoprefixer')()
]
};};
现在可以使用较短的命令运行PostCSS:
npx postcss ./src/scss/main.scss \
--output ./build/css/main.css \
--env development \
--verbose
以下是一些注意事项:
-
--verbose
是可选的:未在中设置postcss.config.js
。 -
Sass语法分析仅在输入是
.scss
文件时才应用。否则,它默认为标准CSS。 -
仅当
--env
设置为时,才输出源映射development
。 -
--watch
仍可以添加以进行自动编译。
如果您希望postcss.config.js
位于另一个目录中,则可以使用--config
-进行引用--config /mycfg/
。在示例项目中,上面的配置位于中config/postcss.config.js
。通过运行引用npm run css:basic
,它调用:
npx postcss src/scss/main.scss \
--output build/css/main.css \
--env development \
--verbose \
--config ./config/
添加更多插件
以下各节提供了PostCSS插件的示例,这些CSS插件可以解析其他.scss
语法或提供超出Sass编译器范围的处理。
使用设计令牌
设计令牌是一种与技术无关的方法,用于存储诸如公司范围内的字体,颜色,间距等变量。您可以将令牌名称/值对存储在JSON文件中:
{
"font-size": "16px",
"font-main": "Roboto, Oxygen-Sans, Ubuntu, sans-serif",
"lineheight": 1.5,
"font-code": "Menlo, Consolas, Monaco, monospace",
"lineheight-code": 1.2,
"color-back": "#f5f5f5",
"color-fore": "#444"}
然后在任何Web,Windows,macOS,iOS,Linux,Android或其他应用程序中引用它们。
Sass不直接支持设计令牌,但是variables
可以将具有名称/值对属性的JavaScript对象传递给现有的postcss-advanced-variables PostCSS插件:
// PostCSS configurationmodule.exports = cfg => {
// import tokens as Sass variables
const variables = require('./tokens.json'); // NEW
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')({ variables }), // UPDATED
require('postcss-nested')(),
require('autoprefixer')()
]
};};
该插件将所有值转换为全局Sass $variables
,可在任何局部使用。可以设置后备值以确保即使变量中缺少变量也可用tokens.json
。例如:
// set default background color to #FFF// if no "color-back" value is set in tokens.json$color-back: #fff !default;
然后可以在任何.scss
文件中引用令牌变量。例如:
body {
font-family: $font-main;
font-size: $font-size;
line-height: $lineheight;
color: $color-fore;
background-color: $color-back;}
在示例项目中,token.json
定义了一个文件,该文件在运行时被加载和使用npm run css:dev
。
添加Sass Map支持
Sass Maps是键值对象。该map-get
函数可以按名称查找值。
下面的示例将媒体查询断点定义为带有respond
mixin的Sass映射,以获取命名值:
// media query breakpoints$breakpoint: (
'small': 36rem,
'medium': 50rem,
'large': 64rem);/*
responsive breakpoint mixin:
@include respond('medium') { ... }
*/@mixin respond($bp) {
@media (min-width: map-get($breakpoint, $bp)) {
@content;
}}
然后可以在同一选择器中定义默认属性和媒体查询修改。例如:
main {
width: 100%;
@include respond('medium') {
width: 40em;
}}
哪个可以编译成CSS:
main {
width: 100%;}@media (min-width: 50rem) {
main {
width: 40em
}}
该postcss-MAP-GET插件添加萨斯地图处理。通过以下方式安装:
npm install --save-dev postcss-map-get
并更新postcss.config.js
配置文件:
// PostCSS configurationmodule.exports = cfg => {
// import tokens as Sass variables
const variables = require('./tokens.json');
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')({ variables }),
require('postcss-map-get')(), // NEW
require('postcss-nested')(),
require('autoprefixer')()
]
};};
添加媒体查询优化
由于我们已经添加了媒体查询,因此将它们组合并按移动优先顺序进行排序将非常有用。例如,以下CSS:
@media (min-width: 50rem) {
main {
width: 40em;
}}@media (min-width: 50rem) {
#menu {
width: 30em;
}}
可以合并成为:
@media (min-width: 50rem) {
main {
width: 40em;
}
#menu {
width: 30em;
}}
这在Sass中是不可能的,但是可以通过PostCSS postcss-sort-media-queries插件来实现。通过以下方式安装:
npm install --save-dev postcss-sort-media-queries
然后将其添加到postcss.config.js
:
// PostCSS configurationmodule.exports = cfg => {
// import tokens as Sass variables
const variables = require('./tokens.json');
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')({ variables }),
require('postcss-map-get')(),
require('postcss-nested')(),
require('postcss-sort-media-queries')(), // NEW
require('autoprefixer')()
]
};};
添加资产处理
资产管理在Sass中不可用,但是postcss-assets使它变得容易。该插件可解析CSS图像URL,添加缓存清除功能,定义图像尺寸,并使用base64表示法内联文件。例如:
#mybackground {
background-image: resolve('back.png');
width: width('back.png');
height: height('back.png');
background-size: size('back.png');}
编译为:
#mybackground {
background-image: url('/images/back.png');
width: 600px;
height: 400px;
background-size: 600px 400px;}
使用以下命令安装插件:
npm install --save-dev postcss-assets
然后将其添加到中postcss.config.js
。在这种情况下,将指示插件在src/images/
目录中找到图像:
// PostCSS configurationmodule.exports = cfg => {
// import tokens as Sass variables
const variables = require('./tokens.json');
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')({ variables }),
require('postcss-map-get')(),
require('postcss-nested')(),
require('postcss-sort-media-queries')(),
require('postcss-assets')({ // NEW
loadPaths: ['src/images/']
}),
require('autoprefixer')()
]
};};
添加缩小
cssnano设置CSS缩小的标准。缩小可能比其他插件花费更多的处理时间,因此只能在生产中使用。
使用以下命令安装cssnano:
npm install --save-dev cssnano
然后将其添加到中postcss.config.js
。在这种情况下,仅当NODE_ENV
设置为以外的其他值时,才会发生缩小development
:
// PostCSS configurationmodule.exports = cfg => {
// import tokens as Sass variables
const variables = require('./tokens.json');
const
dev = cfg.env === 'development',
scss = cfg.file.extname === '.scss';
return {
map: dev ? { inline: false } : false,
parser: scss ? 'postcss-scss' : false,
plugins: [
require('postcss-advanced-variables')({ variables }),
require('postcss-map-get')(),
require('postcss-nested')(),
require('postcss-sort-media-queries')(),
require('postcss-assets')({
loadPaths: ['src/images/']
}),
require('autoprefixer')(),
dev ? null : require('cssnano')() // NEW
]
};};
设置--env
到prodution
触发器缩小(并移除源映射):
npx postcss ./src/scss/main.scss \
--output ./build/css/main.css \
--env prodution \
--verbose
在示例项目中,可以通过运行来编译生产CSS npm run css:build
。
进步到PostCSS?
PostCSS是功能强大且可配置的工具,可以编译.scss
文件并增强(或限制)标准的Sass语言。如果您已经使用PostCSS作为Autoprefixer,则可以在保留您喜欢的语法的同时完全删除Sass编译器。