PostCSS深入学习: 压缩和优化CSS

发布于 大漠

上一节的教程中学习了如何使用PostCSS插件帮助你处理跨浏览器兼容性的样式,特别是如何对IE老版本做降级处理。

在本教程中我们将继续学习如何使用PostCSS插件让你的样式表更加高效,加载更快。这些都可以通过PostCSS插件执行各种压缩和优化。

本教程你将学习如何:

  • 通过@import将多个样式组合为一个,即使你的一些样式来自Bower组件或npm模块,都可以确保你你只需要请求一个单独的http,加载网站的CSS
  • 匹配媒体查询,允许你将多个地点使用相同的媒体查询组合成一个
  • 使用cssnano执行各种优化,删除空白和注释,并且压缩代码

那我们开始吧。

设置您的项目

你需要做的第一件事情是使用Gulp或Grunt设置你的项目。如果你没有一个较好的项目模板,你可以使用Gulp或者Grunt使用最少的代码来达到相同的目的。

你可以阅读前面有关于PostCSS的教程,了解有关于如何使用Gulp或Grunt设置您的项目:

如果你不想从头开始手动设置您的项目,你可以下载本教程中提供的源码附件,提取Gulp或Grunt项目到一个空的文件夹中。

然后在命令终端运行:npm install

安装插件

在本教程中我们将使用两个单独的插件,加上一个插件包。通过运行下面的命令将插件安装到你的项目文件夹:

npm install postcss-import css-mqpacker cssnano --save-dev

现在已经将插件安装好了,让我们继续将需要的配置添加到项目中。

使用Gulp加载插件

如果你使用Gulp,可以在你的gulpfile.js文件中添加下面变量:

var atImport = require('postcss-import');
var mqpacker = require('css-mqpacker');
var cssnano = require('cssnano');

并且在processors数组中添加下面的变量名:

var processors = [
    atImport,
    mqpacker,
    cssnano
];

通过gulp css命令可以做一个快速测试,你可以看到你项目中dest文件夹中添加style.css文件。

使用Grunt添加插件

如果你使用的是Grunt设置项目,可以在你的gruntfile.js文件中的processors对象中添加下面的变量名,并且给指定对应的options参数:

processors: [
  require('postcss-import')(),
  require('css-mqpacker')(),
  require('cssnano')()
]

在命令终端执行grunt postcss命令做一个快速测试。查看你项目的dest文件夹中是否添加了style.css文件。

所有需要的插件都安装和加载到项目中,所以让我们继续学习如何使用它们来压缩和优化CSS。

使用@import压缩文件

很多时候,你的项目不仅仅加载一个样式表,而是会加载多个样式表。为了能更高效加载样式,应尽可能的将样式表合并成一个。

例如,normalize.css是非常常用的一个样式表,如果将它作为独立的样式表在主样式之前加载,这样就又多了一个http请求,因此减缓了加载时间。

使用@Maxime Thirouin的postcss-import插件,遵循@import规则,你可以将normalize.css样式合并到你的主样式表中,如此一来,加载相同的CSS就只需要一个http请求就够了。

使用@import内联加载normalize.css

现在让我们看看在项目中如何通过@importnormalize.css合并到主样式表中。首先需要到下载normalize.css文件,并将它放到你项目中的src文件夹中。

接着在src/style.css文件最顶部加入下面的代码:

@import 'normalize.css';

当你安装好postcss-import插件,它会检测到主样式表中@import引入的normalize.css文件,并且会自动将normalize.css样式合并到你的样式表中。

编译之后,在dest/style.css文件中就应该可以看到normalize.css的样式代码:

/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;.......

你可以使用相同的方法尽可能的交独立的样式结合在一起。只需要在src/style.css文件中通过@import将想要合并的独立样式表引入进来即可。

自动发现Bower Component和Node Module中样式文件

这个插件还有一个非常有用特性,它能够自动发现bower_componentsnode_modules文件夹内的CSS文件位置。

正如上面所说的,你不需要手动安装normalize.css,你只需要在命令行中执行bower install normalize.css --save命令,即可将文件安装到你的项目中。这个时候会自动将最新的normalize.css下载到bower_components/normalize.css文件夹中。

**注:**如果你电脑中没有安装Bower,可以点击这里进行了解。

在你的样式表顶部,使用上面的代码来替代:

@import 'normalize.css/normalize.css';

postcss-import插件会在你的bower_components文件夹中找到normalize.css文件,然后将代码合并到主样式表中。

以同样的方式,可以将node_modules文件夹中的样式引入到样式表中,这也意味着,你可以使用Bowernpm下载,管理依赖关系和更新。这个插件服务非常简单,就是可以将第三方CSS样式文件合并到你的样式表中。

使用@import行内导入样式的方法

通过@import可以将不同来源的CSS文件(比如bower_components/)导入到样式表中,如此一来,可以让你分开来独立管理样式。

例如,你可以创建一个文件来控制你的布局,另外创建一个文件来管理你的配色方案。如果您想改变你的配色方案,你只需遵循这样的过程:

  • 声明颜色的原样式表
  • 修改新颜色代码
  • 将新颜色样式表导入到你的项目
  • 编译创建备用颜色样式表

你可以重复这个程,这样就可以创建多外有效的颜色配色方案。

一些项目使用不同的样式表可以提供多个这样的配色方案,但这样会增加http请求,会影响网站的加载速度。使用这种方法你最后总是只需要请求一个http

有关于postcss-import更多的信息可以点击这里进行了解。

结合匹配的媒体查询

@Kyo Nagashima的css-mqpacker插件可以找到样式表中相同的媒体查询样式合并到一个媒体查询中。这样允许你在写CSS的时候,媒体查询可以重复编写,你也不用担心这样会对你的样式产生冗余代码,而影响你的效率。

让我们来看一个简单的示例,你可能想要重复的媒体查询,比如根据视觉效果编写你的布局。在实际项目中,可能会给布局单独一个样式文件,但这里为了简单起见,我们还是将代码放置在src/style.css文件中。

从一些布局代码开始。将添加一个.column类,并且将其宽度设置为50%,默认情况,这两列并排在一起排列。然后使用一个媒体查询,在较小的屏幕下,让他们从上向下堆栈排列。把下面的代码添加到你的样式表中:

/* LAYOUT */
 
.column {
    width: 50%;
    float: left;
}
 
@media (max-width: 50rem) {
    .column {
        width: 100%;
        float: none;
    }
}

接下来,添加一些视觉效果,比如给列设置一个灰色的边框。第一列使用类名.column_one,第二列使用类名.column_two。我们使用相同的媒体查询,根据列的布局来改变边框样式。

将下面的代码添加到你的样式中:

/* VISUALS */
 
.column_one, .column_two {
    border: 0.0625rem solid #ccc;
}
 
.column_two {
    border-left: 0;
}
 
@media (max-width: 50rem) {
    .column_one, .column_two {
        border: 0.0625rem solid #ccc;
    }
 
    .column_two {
        border-top: 0;
    }
}

重新编译src/style.css文件,可以在dest/style.css中看到编译后的代码。

正如下面代码所示,css-mqpacker插件已经确认了两个媒体查询是相同的,并且将它们组合到一起:

/* LAYOUT */
 
.column {
    width: 50%;
    float: left;
}
 
/* VISUALS */
 
.column_one, .column_two {
    border: 0.0625rem solid #ccc;
}
 
.column_two {
    border-left: 0;
}
 
@media (max-width: 50rem) {
 
    .column {
        width: 100%;
        float: none;
    }
 
    .column_one, .column_two {
        border: 0.0625rem solid #ccc;
    }
 
    .column_two {
        border-top: 0;
    }
}

**注意:**由于使用cssnano插件,你看到的dest/style.css代码是被压缩的。你可以注释到gulpfile.jsgruntfile.js文件中processors数组中的cssnano,就可以看到上面未压缩的代码。

有关于css-mqpacker更多的信息可以点击这里进行了解。

cssnano插件包

@Ben Briggs提供了一个非常强大的CSS优化的插件包cssnano,这个插件包是一个可以即插即用的。它汇集了大约25个插件,只需要执行一个命令,就可以做多方面不同类型的优化。

cssnano优化包括下面一些类型:

  • 删除空格和最后一个分号
  • 删除注释
  • 优化字体权重
  • 丢弃重复的样式规则
  • 优化calc()
  • 压缩选择器
  • 减少手写属性
  • 合并规则

根据上述优化列表,在你的项目中添加一些示例代码。在src/style.css中添加下面的代码:

.css_nano, .css_nano + p, [class*="css_nano"], .css_nano {
    /* This is an example of cssnano in action */
    font-weight: normal;
    margin-top: 1rem;
    margin-bottom: 2rem;
    margin-left: 1.5rem;
    margin-right: 2.5rem;
    font-weight: normal;
    padding: 1.75rem;
    width: calc(50rem - (2 * 1.75rem));
}
 
a {
    text-decoration: none;
    font-weight: bold;
}
 
p {
    font-weight: bold;
}

然后重新编译你的文件。

**注:**你可以注释掉其它代码,这样你可以更清楚的看到结果。

dest/style.css文件中你可以看到代码后的代码:

.css_nano,.css_nano+p,[class*=css_nano]{margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}a{text-decoration:none}a,p{font-weight:700}

看看上面列表中提到的代码清单,然后在比较一下编译前后的示例代码,看看发生了什么变化:

  • 空格、注释和最后一个分号删除掉了
  • font-weight:normalfont-weight:bold都编译为font-weight:400font-weight:700
  • 第二个重复的font-weight:normal规则从.css_nano样式中删除了
  • calc()值被处理成一个静态值
  • .css_nano, .css_nano + p, [class*="css_nano"], .css_nano压缩为.css_nano,.css_nano+p,[class*=css_nano]
  • 手写多个属性margin-top: 1rem; margin-bottom: 2rem; margin-left: 1.5rem; margin-right: 2.5rem;处理成margin:1rem 2.5rem 2rem 1.5rem;
  • apfont-weight: 700;合并在一起

有关于cssnano插件优化的全部列表清单可以点击这里了解。

配置参数和禁用模块

cssnano插件包包含多个独立的插件,你完全可能根据自己的需求进行配置,甚至是完全禁用。

禁用插件,你可以通过cssnano把其参数设置为false。例如,你不想优化字体权重,你可以在gulpfile.jsgruntfile.js文件中这样设置:

// In Gulpfile 'processors' array
cssnano({
    minifyFontWeight: false
})
 
// In Gruntfile 'processors' array
require('cssnano')({
    minifyFontWeight: false
})

你可以按照相同的方法来配置插件的选择,每个是插件名称,然后设置其选项。

例如,使用calc()时,你可以设置小数的精度值(小数点后面的数量)。默认情况之下calc(100% / 2.27)得到的结果是36.23188%,如果你想精确到小位数后面的两位,你可以这样做:

// In Gulpfile 'processors' array
cssnano({
    calc: {precision: 2}
})
 
// In Gruntfile 'processors' array
require('cssnano')({
    calc: {precision: 2}
})

最后calc计算输出的值是36.23%

有关于cssnano参数配置的详细介绍,可以点击这里阅读。

快速总结一下

根据上面介绍的内容,我们做一个快速的总结:

  • postcss-import插件提供了一个更有效的引入内联样式表的方法
  • postcss-import插件可以引入第三方的样式表,也可以使用bower_componentsnpm_modules文件夹中的样式表
  • postcss-import插件可以将样式表分割成多个部分,然后再重新组合它们
  • css-mqpacker插件允许你将多个相同的媒体查询合并到一起
  • cssnano插件汇集了25个不同的插件,提供即插即用,获得压缩和优化样式表的功能
  • cssnano插件可以根据你自己的需求来配置包中的插件

下一节:PreCSS预处理

在接下来的教程中,我们将深入了解PostCSS处理中另一个优秀的插件包PreCSS,这个插件包提供了类似于Sass一样的语法和功能。比如变量、混合宏,扩展等。

如果你对这方面的教程感兴趣,欢迎持续关注本系列教程的相关更新。

本文根据@Kezz Bracey的《Using PostCSS for Minification and Optimization》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/PostCSS/using-postcss-for-minification-and-optimization.htmlNike Zoom Vomero 12