从 SASS 切换到 PostCSS
推动
以前的方法
开关
自从PostCSS发布以来,我一直专门用它来做Autoprefixer。我并没有真正深入研究它的强大之处PostCSS
,以及它如何成为与SASS相媲美的解决方案。
本文将深入探讨我的怀疑,以及我如何使用找到解决方案PostCSS
。
推动
最初让我考虑转换的原因是我对Tailwind CSS很感兴趣。我喜欢它的理念utility libraries
,但发现很难向其他开发者推销。不过,我们一直在寻找优化开发时间的方法,所以Tailwind
感觉这是一个不错的选择。它的设计PostCSS
初衷就是为了满足我们的需求,所以我至少想尝试一下。
以前的方法
我之前的方法是混合使用SASS、BEM、ITCSS和SMACSS。它们解决了以下问题:
SASS
-variables, loops, imports, nested selectors, etc
BEM
- 减少specificity
并允许更容易地添加/修改代码ITCSS
- (与 相同BEM
),但也允许inverted triangle
层次结构specificity
变得越来越具体。SMACSS
- 主要用于modifier classes
,例如.js-is-active, .has-posts, etc
。
这对我来说真的很有效。我见识了它的威力utility libraries
,但我想先让它们进化,以后再尝试。
开关
我不会用细节来烦你,但我经历了许多次迭代,例如:
PostCSS
只是,没有plugins
此外Tailwind
PostCSS + SASS
PostCSS
仅与Tailwind
其他互补plugins
这种方法的核心问题PostCSS + SASS
是不可避免的重复。例如,以下情况无法同时进行:
/**
* cannot set $font-size-px-base in PostCSS
* since SASS gets run first, so would have
* to duplicate code
*/
@function rem($pixels, $context: $font-size-px-base) {
@if (unitless($pixels)) {
$pixels: $pixels * 1px;
}
@if (unitless($context)) {
$context: $context * 1px;
}
@return $pixels / $context * 1rem;
}
/**
* can't use Tailwind variables
* in the SASS function `scale` since
* SASS runs before PostCSS
*/
.selector {
font-size: scale(font-size, theme('fontSize.lg'), theme('fontSize.xl'));
}
/**
* Interpolation was also a nightmare
* I couldn't figure out how to make
* something like this work
* even with PostCSS Simple Vars
*/
.selector {
$path: theme('path.theme');
background-image: url($(path)/test.png);
}
最终解决方案
最终的解决方案PostCSS
仅涉及,Tailwind
以及其他补充plugins
。
当我想到这一点时,我真正使用的SASS
用途是:
imports
mixins
functions
variables
nested selectors
-很少,但最好有,特别是对于伪选择器loops
-非常罕见,但很高兴有
PostCSS
在我意识到他们的插件系统强大之后,我发现他们为所有这些问题提供了解决方案。此外,我还发现一些插件,例如 forfunctions
和mixins
,允许你将Javascript
函数注入到 中PostCSS
。我被深深吸引了。
导入
PostCSS Imports提供与 完全相同的功能SASS Imports
,因此切换很容易。
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'components/btn';
@import 'tailwindcss/utilities';
功能
PostCSS 函数允许您编写函数IN JAVASCRIPT
并将其注入到PostCSS
..IN JAVASCRIPT. I LOVE JAVASCRIPT
// functions.js
let settings = require('./settings');
let rem = (pixels, context = settings.defaults.fontSizePxBase) => {
pixels = parseFloat(pixels);
let result = pixels / context;
return `${result}rem`;
};
module.exports = {
rem,
};
Mixins
PostCSS Mixins与 相同PostCSS Functions
。
// mixins.js
let placeholder = (mixin, immediateSelector = true) => {
let vendors = [
'::-webkit-input-placeholder',
':-moz-placeholder',
'::-moz-placeholder',
':-ms-input-placeholder',
];
return vendors.reduce((prev, vendor) => {
let selector = immediateSelector ? `&${vendor}` : vendor;
prev[selector] = {
'@mixin-content': {},
};
return prev;
}, {});
};
module.exports = {
placeholder,
};
其他值得注意的插件
- PostCSS Nested - 提供
SASS nesting
- PostCSS Simple Vars - 提供简单的
variables
使用方式selectors, etc
- PostCSS PurgeCSS
CSS
-根据你传入的文件 glob删除不必要的内容 - CSSNano - 最小化
CSS
- Autoprefixer
prefixes
-根据浏览器支持删除不必要的内容
PostCSS 配置文件示例
// postcss.config.js
let functions = require('./functions');
let mixins = require('./mixins');
module.exports = function(context) {
/**
* context comes from what you pass
* into `gulp-postcss`, omitting detailing here
* since `gulp` is an implementation detail
*/
let { options } = context;
let plugins = [
require('postcss-import')({
path: [options.paths.components, options.paths.styles, 'node_modules'],
}),
require('tailwindcss')('./tailwind.config.js'),
require('postcss-functions')({
functions,
}),
require('postcss-mixins')({
mixins,
}),
require('postcss-nested'),
require('postcss-simple-vars'),
require('autoprefixer'),
];
return {
plugins,
};
};
我希望这至少能引起你的兴趣PostCSS
,并让你了解它的强大plugin
系统能为你的下一个项目提供什么。