PostCSS 快速入门使用

发布于 2024-05-03 21:19:15 字数 9682 浏览 26 评论 0

PostCSS 是一套利用 JS 插件实现的用来改变 CSS 的工具.这些插件能够支持变量和混合语法,转换未来 CSS 语法,内联图片,还有更多。

初识 PostCSS

如果你第一次听说 PostCSS 这个东西,那么请看下面摘自官方 Github 的介绍:

PostCSS is a tool for transforming CSS with JS Plugins. These plugins can support variables and mixins, transpile future CSS syntax, inline images, and more

翻译成中文的意思如下:

PostCSS 是一套利用 JS 插件实现的用来改变 CSS 的工具.这些插件能够支持变量和混合语法,转换未来 CSS 语法,内联图片,还有更多

我们用过 LessSASS 等工具来对 CSS 做 预处理 操作,按照它们约定的语法来书写并且最终转换成可用的样式,这付出的代价是必须先熟悉这个工具的书写语法

随着近几年 GruntGulpWebpack 等自动化工具的兴起, 组合式应用 变得非常的热门,那 PostCSS 存在的意义是什么呢?答案是:CSS 生态系统

PostCSS 拥有非常多的插件,诸如自动为 CSS 添加浏览器前缀的插件 autoprefixer 、当前移动端最常用的 pxrem 插件 px2rem ,还有支持尚未成为 CSS 标准但特定可用的插件 cssnext ,还有很多很多。就连著名的 Bootstrap 在下一个版本 Bootstrap 5 也将使用 PostCSS 作为样式的基础。

一句话来概括 PostCSS:CSS 编译器能够做到的事情,它也可以做到,而且能够做得更好

快速使用 PostCSS

上面大致介绍了 PostCSS ,也许我们并没有在头脑里形成对它的认知,那下面我们就通过一个简单地实例来看看如何使用 PostCSS

PostCSS 得益于插件,支持 Grunt,Gulp,webpack,Broccoli,Brunch 还有 ENB,这里我们将以 Gulp 作为实例来讲。

环境准备

创建并进入我们的实例目录

mkdir postcss-demo && cd postcss-demo

然后快速生成 package.json 文件

# --yes 参数能够帮助我们快速生成默认的 package.json
npm init --yes

将上面创建的 package.json 文件的 main 参数改为 gulpfile.js ,然后安装我们所需的依赖

# gulp 跟 gulp-postcss 是必须的,后面两个插件为了演示用途
npm i gulp gulp-postcss autoprefixer autoprefixer-core cssnext --save-dev -d

创建 gulpfile.js

# 这里用命令行进行创建,你也可以手动新建
touch gulpfile.js

修改 gulpfile.js

将下面代码贴进 gulpfile.js

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var cssnext = require('cssnext');

//定义 css 任务
gulp.task('css', function(){
  //定义 postcss 任务流数组
  var processors = [
    autoprefixer({
      browsers:['last 3 version'],
      cascade: false,
      remove: false
    }),
    cssnext()
  ];
  return gulp.src('./src/css/*.css')
             .pipe(postcss(processors))
             .pipe(gulp.dest('./dist'));
});

创建示例样式

在项目根目录下创建 src 目录,再在 src 目录下面创建 css 目录,然后创建 style.css 文件

# 这里用命令创建,你也可以手动创建
mkdir -p src/css && touch style.css

编辑样式如下:

h1{
  display:flex;
}

:root {
--fontSize: 1rem;
--mainColor: #12345678;
--highlightColor: hwb(190, 35%, 20%);
}

body {
color: var(--mainColor);

font-size: var(--fontSize);
line-height: calc(var(--fontSize) * 1.5);
padding: calc((var(--fontSize) / 2) + 1px);
}

运行实例

一切准备就绪之后可以在项目根目录下执行刚才我们定义的任务

gulp css

如果不出什么意外的话就会在根目录下面生成一个 dist 文件夹,里面有一个样式文件,内容如下:

body{
  display:-webkit-flex;
  display:-ms-flexbox;
  display:-webkit-box;
  display:flex;
}

body {
color:#123456;
color:rgba(18, 52, 86, 0.47059);

font-size:16px;
font-size:1rem;
line-height:24px;
line-height:1.5rem;
padding:calc(0.5rem + 1px);
}

我们可以看到我们写的样式自动添加了浏览器前缀,并且一些未来 CSS 语法也被转换了。

了解 PostCSS

通过上面的实例我们应该知道 PostCSS 的使用方法,此时让我们先回想一下 CSS 预处理器 的使用历程:

  1. 学习该 CSS 预处理器的语法特性,诸如:变量定义、嵌套、继承
  2. 在特定后缀名(.less/.scss 等) 的文件按照上面的语法进行编写
  3. 通过 Gulp/Grunt/Webpack 等自动化工具或者手动编译成 CSS 样式

PostCSS 的使用历程:

  1. 直接按照 CSS 标准语法来书写 CSS 样式文件
  2. 通过 Gulp/Grunt/Webpack 等自动化工具加载 PostCSS 插件转换输出

通过对比我们类比一个结论:CSS 预处理器好比给你一个工具箱,工具箱里面有什么东西该怎么拿已经跟你约定好,你必须按照这个规则来拿;而 PostCSS 好比给你一个盒子,你可以从旁边选择自己需要的工具放进盒子打包拿走,如果还不够用你可以自己造一个工具

深入 PostCSS

PostCSS 自身只包括了 CSS 分析器CSS 节点树 APIsource map 生成器CSS 节点拼接器 ,而基于 PostCSS 的插件都是使用了 CSS 节点树 API 来实现的。

我们都知道 CSS 的组成如下:

element {
  prop1 : rule1 rule2 ...;
  prop2 : rule1 rule2 ...;
  prop2 : rule1 rule2 ...;
  ...
}

也就是一条一条的样式规则组成,每一条样式规则包含一个或多个属性跟值。所以 PostCSS 的执行过程大致如下:

  1. Parser
    利用 CSS 分析器 读取 CSS 字符内容,得到一个完整的 节点树
  2. Plugin
    对上面拿到的 节点树 利用 CSS 节点树 API 进行一系列的转换操作
  3. Plugin
    利用 CSS 节点拼接器 将上面转换之后的节点树重新组成 CSS 字符
  4. Stringifier
    在上面转换期间可利用 source map 生成器 表明转换前后字符的对应关系

PostCSS 性能

在 PostCSS 官方推特上看到,由 JavaScript 编写的 PostCSS 比 C++编写的 libsass 还要快 3 倍,下面来自官方推特的截图:

PostCss

如果你对上面的性能截图有疑问,可以亲自来 这里 测试看看。

开始编写自己的 PostCSS 插件

PostCSS 在自己的 Github 上放了一些常用的插件,更多的插件可以在 postcss.parts 进行搜索。

但有时候已有的插件不满足我们的需求,这个时候需要编写自己的 PostCSS 插件,下面我们将一步步创建一个简单的插件,这个插件功能非常简单,如下:

/* 
  文件位置:src/css/style.css
 */
h1 {
  font-family: "\5FAE\8F6F\96C5\9ED1",fontstack('Arial');
}

当输入上面的样式时,会生成下面的样式:

/*
  文件位置:dist/style.css
 */
h1 {
  font-family: "\5FAE\8F6F\96C5\9ED1",tahoma,arial;
}

环境准备

我们将以 Gulp 作为基础来实现我们的插件,首先创建项目文件夹

mkdir postcss-plugin && cd postcss-plugin

然后快速创建 package.json 文件:

npm init --yes

紧接着先安装必备的包

npm i gulp postcss gulp-postcss --save-dev -d

再创建 gulpfile.js 并且输入下面内容:

var gulp = require('gulp');
var postcss = require('gulp-postcss');

gulp.task('css', function(){
  var processors = [
  ];
  return gulp.src('./src/css/*.css')
             .pipe(postcss(processors))
             .pipe(gulp.dest('./dist'));
});

创建插件文件夹

我们在执行 npm install 安装的包都放置在 node_modules 文件夹下面,这里我们创建 PostCSS 的插件文件夹,注意:PostCSS 的插件命名格式为:postcss-插件名字

# 这里采用命令新建文件夹,你也可以手动创建
mkdir node_modules/postcss-fontstack

创建插件入口文件

现在我们可以在 postcss-fontstack 文件夹创建入口文件 index.jsPostCSS 创建插件的方式如下:

var postcss = require('postcss');
module.exports = postcss.plugin('插件名字', function 插件名字(选项){
  //这里写插件代码
})

那我们可以在 index.js 里面贴入下面代码:

var postcss = require('postcss');

modules.exports = postcss.plugin('fontstack', function fontstack( options ){
  return function( css ){
    options = options || {};

    var fontstack_config = {
      'Arial': 'tahoma,arial',
      'Times New Roman': 'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif'
    };

    function toTitleCase( str ){
      return str.replace(/\w\S*/g,function( txt ){
          return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
      });
    }

    // css.walkRules 方法用来遍历每一条 css 规则
    css.walkRules( function( rule ){
        // walkDecls 方法用来解析属性跟值
        rule.walkDecls( function( decl, i ){
            var value = decl.value;
            if( value.indexOf( 'fontstack(' ) !== -1 ){
                var fontstack_requested = value.match(/\(([^)]+)\)/)[1].replace(/["']/g,"");
                fontstack_requested = toTitleCase( fontstack_requested );

                var fontstack = fontstack_config[ fontstack_requested ];

                var firstFont = value.substr( 0, value.indexOf('fontstack(') );

                var newValue = firstFont + fontstack;

                decl.value = newValue;
            }
        });

    });
  }
});

gulpfile.js 引入上面的插件,代码如下:

var gulp = require('gulp');
var postcss = require('gulp-postcss');

gulp.task('css', function(){
  var processors = [
  ];
  return gulp.src('./src/css/*.css')
             .pipe(postcss(processors))
             .pipe(gulp.dest('./dist'));
});

运行实例

在项目根目录下运行实例,最终实现我们的效果

gulp css

再谈 PostCSS

基于 PostCSS 能够做到很多 CSS 预处理器 做不到的事情,未来发展前景还是挺不错的,而且最新的 Atom 编辑器也可以下载插件来支持 PostCSS 这种语法。

但这就意味着 CSS 预处理器 过时了么?不会。 PostCSS 的出现并不是为了替换掉之前的技术,只是提供多一种思路让我们去考虑,就比如 Sass 编译后再加 autoprefixer 自动补齐浏览器前缀这种做法当前还是比较流行的。

再回到文章最开始说的, PostCSS 其实是在打造一个改变 CSS 开发方式的生态系统。也许暂时我们还是保持传统的开发方式,但未来对于 PostCSS 我还是保持关注,它是值得期待的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
23 人气
更多

推荐作者

玍銹的英雄夢

文章 0 评论 0

我不会写诗

文章 0 评论 0

十六岁半

文章 0 评论 0

浸婚纱

文章 0 评论 0

qq_kJ6XkX

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文