# Using PostCSS for Minification and Optimization

This post is part of a series called PostCSS Deep Dive.
Using PostCSS for Cross Browser Compatibility
PostCSS Deep Dive: Preprocessing with “PreCSS”

In the last tutorial you learned how to use PostCSS to help make your stylesheets more cross browser compatible, in particular dealing with issues arising from support for legacy versions of IE.

In this tutorial we’re going to learn how to make your stylesheets more efficient and load faster, by using PostCSS to perform various minification and optimization operations.

You’ll learn how to:

• Combine multiple stylesheets into one via the @import rule, even if some of your stylesheets are coming from Bower components or npm modules, ensuring you need only a single http request to load your site’s CSS.
• Combine matching media queries into one, allowing you to use the same media query in multiple locations during development but still end up with the efficiency of consolidated queries in your final stylesheet.
• Use the cssnano pack to perform all kinds of optimizations from stripping white space and comments to minifying certain types of code and much more.

Let’s get started!

The first thing you’ll need to do is setup your project to use either Gulp or Grunt, depending on your preference. If you don't already have a preference for one or the other I recommend using Gulp as you'll need less code to achieve the same ends, so you should find it a bit simpler to work with.

You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials

respectively.

If you don't want to manually setup your project from scratch though, you can download the source files attached to this tutorial, and extract either the provided Gulp or Grunt starter project into an empty project folder. Then with a terminal or command prompt pointed at the folder run the command npm install.

## Install Plugins

For this tutorial we’re going to be using two individual plugins, plus a plugin pack. Install them by running the following command inside your project folder:

If you’re using Gulp, add these variables under the variables already in the file:

Now add each of those new variable names into your processors array:

Do a quick test that everything is working by running the command gulp css then checking that a new “style.css” file has appeared in your project’s “dest” folder.

If you’re using Grunt, update the processors object, which is nested under the options object, to the following:

Do a quick test that everything is working by running the command grunt postcss then checking that a new “style.css” file has appeared in your project’s “dest” folder.

That has all the plugins installed and loaded, so let’s move onto learning how to use them for minification and optimization.

## Inline/Combine Files with @import

Rather than individually loading multiple stylesheets, it’s more efficient wherever possible to combine your stylesheets into one.

For example, use of Normalize.css is very common, but, if you load it as a standalone stylesheet before your main stylesheet, it requires multiple http requests, hence slowing down load time.

However if you use the postcss-import plugin by Maxime Thirouin, you can combine Normalize.css into your main stylesheet, via use of the @import rule, giving you the same CSS with only one http request.

### @import then Inline Normalize.css

As you already have postcss-import installed, that’s all you have to do. It will see the @import rule and automatically inline the code from the normalize.css file into your stylesheet.

Compile your file, and when you look at your “dest/style.css” file you should see the entire contents of “normalize.css” therein:

You can use this same process to combine as many separate stylesheets as you need to. Just place @import lines in your “src/style.css” file wherever you want the inlined code to be inserted.

### Automatic Bower Component and Node Module Discovery

One very helpful feature of this plugin is its ability to automatically discover CSS files situated inside your “bower_components” or “node_modules” folder.

For example, rather than manually downloading “normalize.css” as we did above, you could instead just run the command bower install normalize.css --save in your project. This would automatically download the latest “normalize.css” file into the “bower_components/normalize.css” folder.

Note: If you don’t have Bower setup on your computer learn how here.

At the top of your stylesheet, you could now instead use this line:

The postcss-import plugin will look inside your “bower_components” folder and find “normalize.css”, then proceed to inline it just as in the previous example.

The same process can be followed for any stylesheets that are in your “node_modules” folder, meaning you can use either Bower or npm to handle downloads, dependency management and updates. When using either service this plugin gives you an easy means of combining third party CSS files into your own stylesheets.

### Ways to Leverage @import Inlining

Inlining imported CSS files in this way is not only a very efficient way of combining files from different sources, such as Bower components, it also gives you the option of organizing your project into multiple separate stylesheets.

For example, you might create one file to control your layout, and another to control your color scheme. If you wanted to change your color scheme you could then follow a process like this:

1. Duplicate original color stylesheet
2. Modify it with new color codes
3. Import the new color stylesheet into your project
4. Compile to create alternate colored stylesheet

You could then repeat this process as many times as you wanted, making it efficient to create multiple color schemes for the same design.

Some projects use separate stylesheets to provide multiple color schemes like this, but in the process create slowdown from added http requests. With this approach you always end up with just one http request, despite having a lot of freedom in what might be included in your single stylesheet.

## Combine Matching Media Queries

The css-mqpacker plugin by Kyo Nagashima will find matching media queries in your stylesheet and combine them into one. This allows you to organize your CSS how you please in your development stylesheets, repeating media queries if you need to, without concern over any loss of efficiency in your production stylesheet.

Let’s put together an example of the type of use case where you might want to repeat media queries, such as if you’re organizing your design’s layout and visuals separately. In a real project this might mean using completely separate files, one for layout and one for visuals, but for the sake of simplicity we’ll do this all in our “src/style.css” file.

We’ll start with some layout code. We’ll add a .column class that will make two 50% width columns sit side by side, by default. Then we’ll use a media query to have them stack on top of each other at smaller sizes. Add this code to your stylesheet:

Next we’ll add some visuals to set a gray border around our columns. The first column will have the class .column_one and the second will have the class .column_two. We’re going to use the same media query as we did with our layout to change up how we apply a border to our columns, depending on whether they’re sitting side by side or one on top of the other.

Now, recompile your “src/style.css” file and take a look at the resulting “dest/style.css” content.

As you can see in the code below, the css-mqpacker plugin has identified the two matching media queries, and combined them into one:

Note: The above code will be minified in your “dest/style.css” file due to the cssnano plugin. To see the code unminified, temporarily comment out cssnano from your Gulpfile or Gruntfile’s processors array.

## cssnano Plugin Pack

For comprehensive and multifaceted CSS optimization, the cssnano pack by Ben Briggs is a very powerful option, yet one that is pretty much plug and play. It brings together around twenty-five plugins, and can perform an impressive number of different types of optimization.

Among a long list of optimizations, it can:

• Strip whitespace and final semicolons
• Optimize font weights
• Optimize calc() use
• Minify selectors
• Minimize longhand properties
• Merge rules

We’re going to process some example code in your project that will see all of the above optimizations applied.

Note: you may wish to comment out any code you already had, so you can clearly see the results.

In your “dest/style.css” file you should now see the optimized code:

Have a look through the list of optimizations mentioned in the bullet list above, then compare the example code before and after compilation to see how each one of these changes takes place:

• Whitespace, comments and final semicolons are gone
• font-weight: normal and font-weight: bold are converted to font-weight: 400 and font-weight: 700
• The second, repeated instance of the rule font-weight: normal; has been removed from the .css_nano style
• The calc() property has been reduced to a static value
• The selectors .css_nano, .css_nano + p, [class*="css_nano"], .css_nano have been minified to .css_nano,.css_nano+p,[class*=css_nano]
• The longhand properties margin-top: 1rem; margin-bottom: 2rem; margin-left: 1.5rem; margin-right: 2.5rem; have been reduced to margin:1rem 2.5rem 2rem 1.5rem;
• The a and p styles have been merged to share their common font-weight: 700; setting

For a full list of optimizations cssnano provides check out: http://cssnano.co/optimisations/

### Configuring Options and Disabling Modules

There are several independent plugins employed by the cssnano pack, and you may wish to configure settings for, or fully disable, some of them.

To disable a plugin, pass its name in your options for cssnano with the setting “false” applied. For example, if you don’t want to optimize font weights set the following in your Gulpfile/Gruntfile:

You can follow the same approach to configure options for a plugin, giving the name of the plugin first then setting its options.

For example, you can set the precision, (number of decimal places), the calc plugin should use. By default calc( 100% / 2.76 ) would give you 36.23188%. But if you wanted to trim that precision down to two decimal places you could do it like so:

The calc value would now output to 36.23%.

## Quick Recap

Let’s have a rundown of what we covered above:

• The postcss-import plugin gives you an efficient way to inline stylesheets.
• It can be used to combine third party stylesheets, including through auto-discovery in your “bower_components” or “npm_modules” folder.
• It can be used to allow you to split your stylesheets into parts, then recombine them later.
• The css-mqpacker plugin allows you to duplicate media queries so you can organize your CSS how you please, including into separate files, and then have all matching media queries combined in your final stylesheet.
• The cssnano pack brings together around 25 different plugins, giving plug and play access to a long list of minification and optimization functions.
• It can be configured to use whichever included plugins you want, with the options you want.

## Up Next: Preprocessing with PreCSS

In the next tutorial we’ll dive into using PostCSS for preprocessing via an excellent plugin pack named PreCSS. This pack gives immediate access to Sass-like syntax and functionality, with variables, mixins, conditionals, extends and more.

See you in the next tutorial!