tag:webdesign.tutsplus.com,2005:/categories/postcssEnvato Tuts+ Web Design - PostCSS2015-11-10T14:29:30Ztag:webdesign.tutsplus.com,2005:PostPresenter/cms-24605PostCSS Deep Dive: Create Your Own Plugin<p>As I’m sure you’ve well and truly gathered by this point, what makes PostCSS amazing is its thriving plugin ecosystem. And a huge reason there are so many great plugins, with more coming out all the time, is that PostCSS makes creating your own plugin so accessible for anyone who has some experience with JavaScript.</p><p>You don’t need special permission to make a PostCSS plugin; if you want to make one, you just go right ahead and make it. Through this freedom you have the ability to turn your CSS development processes into anything you want them to be, not to mention the opportunity to share your work with other members of the rapidly growing PostCSS community.</p><p>In this tutorial you’ll learn how to create a basic plugin of your own for PostCSS. We won’t be going too heavily into the plugin API, and we won’t use any super hardcore coding. I myself am a front-end developer, and my JavaScript skills are at the level you would expect them to be for a front-end person, yet that didn’t stop me making my first PostCSS plugin in just a few hours.</p><p>Follow along and see for yourself just how approachable PostCSS plugin development can be!</p><h2>What We’re Going to Build</h2><p>We’ll be creating a plugin that allows for easy insertion of font stacks into <code class="inline">font-family</code> declarations via the following syntax:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", fontstack("Arial");
}</pre><p>After compilation, the above code will turn into:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
}</pre><h2>Set Up a Project to Work Inside</h2><p>Even though you’re creating your own plugin, you’ll still need to start by creating an empty Gulp or Grunt project. You’ll be loading your plugin into this project in the same way you’ve been using other people’s plugins throughout this series.</p><p>You can read about how to set up Gulp or Grunt projects for PostCSS in the previous tutorials:</p><ul>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a></li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>If you don’t want to manually set up your project from scratch, though, you can <a href="https://github.com/tutsplus/postcss-deep-dive-create-your-own-plugin/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.</p><h2>Create a Basic Plugin Shell</h2><p>Create a folder in “node_modules” named “postcss-myplugin”. It’s common to use the prefix <code class="inline">postcss-</code> to make it clear your plugin is for PostCSS.</p><p>All PostCSS plugins are node modules, so we’ll need to turn your new folder into one. Open up a terminal/command prompt, pointed at the newly created folder, and run <code class="inline">npm init</code>. This will perform the basic setup of a node module, so just follow the prompts that come up in your terminal, leaving the “entry point” field as the default “index.js”.</p><p>When this is done, with your terminal still pointed at the folder, run the command <code class="inline">npm install postcss --save</code>. This will install PostCSS as a dependency for this module, something all PostCSS plugins need to do.</p><p>Create a file named “index.js” in the “postcss-myplugin” folder. Add this code to load in the main postcss module:</p><pre class="brush: javascript noskimlinks noskimwords">var postcss = require('postcss');</pre><p>Then below it add this basic wrapper that will surround our plugin’s processing code:</p><pre class="brush: javascript noskimlinks noskimwords">var postcss = require('postcss');
module.exports = postcss.plugin('myplugin', function myplugin(options) {
return function (css) {
options = options || {};
// Processing code will be added here
}
});</pre><h2>Load Your New Plugin</h2><p>Now we’re ready to load your newly created plugin into your project. It won’t do anything yet, but we just want to get the essential setup in place.</p><h3>Load the Plugin via Gulp</h3><p>If you're using Gulp, add this variable under the one already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var myplugin = require('postcss-myplugin');</pre><p>Now add the new variable name into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
myplugin
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> and checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load the Plugin via Grunt</h3><p>If you're using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('postcss-myplugin')()
]</pre><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> and checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h2>Add the Plugin Functionality</h2><h3>Add Test CSS</h3><p>Before we start adding processing code to our plugin, we’re going to add some test code to our stylesheet that the plugin can work on.</p><p>To your “src/style.css” file add this CSS:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", fontstack("Arial");
}</pre><p>Right now, because our plugin isn’t doing anything yet, if you compile your CSS you’ll just see exactly the same code copied straight into your “dest” folder's “style.css” file.</p><h3>Loop Through the Rules and Declarations</h3><p>Now we want to start scanning the CSS of our file so we can find any instances of <code class="inline">fontstack()</code> and process them. To get started on this, add the following code after the <code class="inline">options = options || {};</code> line:</p><pre class="brush: javascript noskimlinks noskimwords"> css.walkRules(function (rule) {
rule.walkDecls(function (decl, i) {
});
});</pre><p>Using <a href="https://github.com/postcss/postcss/blob/master/docs/api.md#containerwalkrulesselectorfilter-callback" rel="external" target="_blank">walkRules()</a> in the first line iterates through every rule in your CSS; a rule is basically your selector and the styles you’ve set between its curly braces. In our test CSS a rule would be:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", fontstack("Arial");
}</pre><p>Then, inside each rule, <a href="https://github.com/postcss/postcss/blob/master/docs/api.md#containerwalkdeclspropfilter-callback" rel="external" target="_blank">walkDecls()</a> iterates through every declaration; a declaration is essentially each line in the style. In the above CSS, a declaration would be:</p><pre class="brush: css noskimlinks noskimwords">font-family: "Open Sans", fontstack("Arial");</pre><h3>Check if <code class="inline">fontstack()</code> Syntax Is Used</h3><p>As we iterate through each declaration using the code we just added, the current declaration is represented by <code class="inline">decl</code>, which gives us access to both the declaration’s property and its value via <code class="inline">decl.prop</code> and <code class="inline">decl.value</code> respectively.</p><p>With our example CSS, <code class="inline">decl.prop</code> would give us <code class="inline">font-family</code> and <code class="inline">decl.value</code> would give us <code class="inline"> "Open Sans", fontstack("Arial")</code>.</p><p>We want to check every <code class="inline">decl.value</code> in our stylesheet to see if it contains the string <code class="inline">fontstack(</code>. If it does, we know someone is trying to use our plugin to add a font stack to their CSS.</p><p>Inside the <code class="inline">walkDecl()</code> loop, add:</p><pre class="brush: javascript noskimlinks noskimwords"> var value = decl.value;
if (value.indexOf( 'fontstack(' ) !== -1) {
console.log("found fontstack");
}</pre><p>First we’re taking <code class="inline">decl.value</code> and storing it in the variable <code class="inline">value</code>. Any changes to <code class="inline">decl.value</code> will be sent into the compiled stylesheet; we’re storing its contents in the variable <code class="inline">value</code> so we can mess around with it.</p><p>Then we’re using the <a href="http://www.w3schools.com/jsref/jsref_indexof.asp" rel="external" target="_blank">indexOf()</a> method to search our new <code class="inline">value</code> variable for the string <code class="inline">fontstack(</code>. If it’s found, we’re logging “found fontstack” to the console so we can check if everything is working thus far.</p><p>Run <code class="inline">gulp css</code> or <code class="inline">grunt postcss</code> and you should see “found fontstack” output once in your terminal/command prompt.</p><h3>Define Some Fontstacks</h3><p>Now that our plugin is able to locate instances of <code class="inline">fontstack()</code> in our stylesheet, we can get ready to convert that instance into a font stack, i.e. a list of font names. But before we can do that, we need to first define these font stacks.</p><p>At the top of your file, under the existing <code class="inline">postcss</code> variable, create a variable named <code class="inline">fontstacks_config</code>. We’re going to turn this variable into an object containing key-value pairs.</p><p>For each entry in the object, the key should be the first font in the font stack, e.g. <code class="inline">'Arial'</code>. It will be the string a user passes to specify the font stack they want to use, e.g. <code class="inline">fontstack("Arial")</code> or <code class="inline">fontstack("Times New Roman")</code>.</p><p>The value in each pair should be a string of the full list of fonts contained in the font stack, e.g. <code class="inline">'Arial, "Helvetica Neue", Helvetica, sans-serif'</code>.</p><p>Add two entries to your <code class="inline">fontstacks_config</code> object, one for 'Arial' and one for 'Times New Roman', using the font stacks provided by <a href="http://www.cssfontstack.com/" target="_self">CSS Font Stack</a>.</p><p>Your <code class="inline">fontstacks_config</code> variable should look like this:</p><pre class="brush: javascript noskimlinks noskimwords">// Font stacks from http://www.cssfontstack.com/
var fontstacks_config = {
'Arial': 'Arial, "Helvetica Neue", Helvetica, sans-serif',
'Times New Roman': 'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif'
}</pre><h3>Check Which Fontstack Is Requested</h3><p>The first thing we need to do when we find an instance of <code class="inline">fontstack()</code> being used is to figure out which font stack the user has requested, i.e. what string they have set between the brackets. </p><p>For example, if a user entered <code class="inline">fontstack("Arial")</code> we would want to extract the string <code class="inline">Arial</code>. The reason we want this string is it will give us a key we can use to look up the corresponding font stack from our <code class="inline">fontstacks_config</code> object.</p><p>Add this code immediately inside the <code class="inline">if</code> statement we added earlier, replacing the <code class="inline">console.log("found fontstack");</code> line:</p><pre class="brush: javascript noskimlinks noskimwords">// Get the name of the fontstack requested by matching the string inside the brackets of fontstack().
// Then replace any double or single quotes therein.
var fontstack_requested = value.match(/\(([^)]+)\)/)[1].replace(/["']/g, "");</pre><p>We are performing two steps here to extract the name of the fontstack as a string.</p><p>First we use the <a href="http://www.w3schools.com/jsref/jsref_match.asp" rel="external" target="_blank">match()</a> method to find whatever string is between the brackets in our value. This would give us a string like <code class="inline">"Arial"</code> or <code class="inline">'Arial'</code>.</p><p>We only want the font name, without any double or single quotes, so we then use the <a href="http://www.w3schools.com/jsref/jsref_replace.asp" rel="external" target="_blank">replace()</a> method to strip them from the string, leaving us with an unquoted string such as <code class="inline">Arial</code>.</p><p>This string is stored in the <code class="inline">fontstack_requested</code> variable.</p><h3>Title Case the Requested Fontstack</h3><p>We’re going to use our newly created <code class="inline">fontstack_requested</code> variable to look up a font stack from our <code class="inline">fontstack_config</code> option. The tricky part is the keys in this object are case sensitive, so if we try to look up the <code class="inline">Arial</code> entry with the key <code class="inline">arial</code> it will fail.</p><p>To solve this, we’re going to “Title Case” the string, so for example <code class="inline">times new roman</code> would be converted to <code class="inline">Times New Roman</code>. We’ll be doing this via a short custom function.</p><p>Under your <code class="inline">fontstacks_config</code> variable add this <code class="inline">toTitleCase()</code> function:</p><pre class="brush: javascript noskimlinks noskimwords">// Credit for this function to http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript/196991#196991
function toTitleCase(str) {
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}</pre><p>Now we’ll apply this function to our <code class="inline">fontstack_requested</code> variable. Under the line where you created the <code class="inline">fontstack_requested</code> variable, add this code:</p><pre class="brush: javascript noskimlinks noskimwords">// Title case the words in the font name, just in case the user didn't do it themselves
fontstack_requested = toTitleCase(fontstack_requested);</pre><p>This passes the <code class="inline">fontstack_requested</code> variable through our <code class="inline">toTitleCase()</code> function, updating its value.</p><h3>Lookup Fontstack From Config</h3><p>Now we have our <code class="inline">fonstack_requested</code> variable set correctly, we can use it to look up the corresponding font stack. After the line you just added, insert this code:</p><pre class="brush: javascript noskimlinks noskimwords">// Lookup the requested fontstack in the fontstack_config object
var fontstack = fontstacks_config[fontstack_requested];</pre><p>This finds the value in the <code class="inline">fontstacks_config</code> object that has a key matching the string contained in our <code class="inline">fontstack_requested</code> variable. </p><p>For example, if <code class="inline">fontstack_requested</code> contains the string <code class="inline">Arial</code>, the entry in <code class="inline">fontstacks_config</code> with the key <code class="inline">Arial</code> will be found and the value <code class="inline">'Arial, "Helvetica Neue", Helvetica, sans-serif'</code> will be returned.</p><p>This returned value is then stored in the variable <code class="inline">fontstack</code>.</p><h3>Check for Fonts Set Before fontstack()</h3><p>Now we have our font stack string retrieved and ready to be inserted into the CSS, but there’s still one more thing we need to do. You’ll recall in our test code we included the font "Open Sans" as the preferred font, with the font stack acting as a fallback. We also need to retrieve this font name from the value so it can be added to the CSS we insert into the processed stylesheet.</p><p>Below the <code class="inline">fontstack</code> variable line, add this code:</p><pre class="brush: javascript noskimlinks noskimwords">// Find and store any font names that might be already be in the value, before the fontstack() call
var first_font = value.substr(0, value.indexOf('fontstack('));</pre><p>This code uses the <a href="http://www.w3schools.com/jsref/jsref_substr.asp" rel="external" target="_blank">substr()</a> method to find any content between the beginning of our <code class="inline">value</code>, (represented by 0), and our <code class="inline">fontstack()</code> instance (located by using the <a href="http://www.w3schools.com/jsref/jsref_indexof.asp" rel="external" target="_blank">indexOf()</a> method). Whatever content is found is stored in the variable <code class="inline">first_font</code>.</p><p>For example, in our test code <code class="inline">value</code> is equal to <code class="inline"> "Open Sans", fontstack("Arial")</code>, so the <code class="inline">first_font</code> variable will be set as <code class="inline"> "Open Sans", </code>.</p><h3>Create a New Value</h3><p>We now have all the pieces we need to create a new value with which to replace our test code’s original value of <code class="inline"> "Open Sans", fontstack("Arial")</code>.</p><p>After the last code you added, insert this code:</p><pre class="brush: javascript noskimlinks noskimwords">// Create the new value for this rule by combining the first_font and fontstack variables
var new_value = first_font + fontstack;</pre><p>Here we’re combining our <code class="inline">first_font</code> and <code class="inline">fontstack</code> variables into a single string and storing it in the variable <code class="inline">new_value</code>. </p><p>In our test code, this would mean combining <code class="inline"> "Open Sans", </code> and <code class="inline">Arial, "Helvetica Neue", Helvetica, sans-serif</code>.</p><p>Our <code class="inline">new_value</code> variable would then hold the string <code class="inline"> "Open Sans", 'Arial, "Helvetica Neue", Helvetica, sans-serif'</code>.</p><p>This now gives us the complete value that we want to add into the processed stylesheet so that: </p><pre class="brush: css noskimlinks noskimwords">font-family: "Open Sans", fontstack("Arial"); </pre><p>... is transformed into:</p><pre class="brush: css noskimlinks noskimwords">font-family: "Open Sans", 'Arial, "Helvetica Neue", Helvetica, sans-serif';</pre><h3>Send the New Value Back to the Stylesheet</h3><p>Now that we have our new value ready to be inserted into the processed stylesheet, all we have to do is update <code class="inline">decl.value</code>. PostCSS will take care of the rest, adding the new value into the processed CSS for us.</p><p>Add this code after the last line you added:</p><pre class="brush: javascript noskimlinks noskimwords">// Send the new value back into the stylesheet
decl.value = new_value;</pre><p>This sets <code class="inline">decl.value</code> to equal the content of our <code class="inline">new_value</code> variable.</p><h3>Test Your Plugin</h3><p>Your plugin is now good to go. Give it a whirl by compiling your stylesheet with <code class="inline">gulp css</code> or <code class="inline">grunt postcss</code> (with your terminal pointed at your project folder, not your plugin folder).</p><p>Your “dest/style.css” file should now show a complete font stack:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
}</pre><h3>(Optional) Add User-Configurable Fontstacks Options</h3><p>You may wish to allow users of your plugin to set their own options, in the same way you have been setting options as you’ve used PostCSS plugins throughout this series.</p><p>We want users to be able to set a <code class="inline">fontstacks</code> option, either adding extra font stacks or redefining existing font stacks, for example:</p><pre class="brush: javascript noskimlinks noskimwords">fontstacks: {
'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif',
'Arial': 'Arial, "Comic Sans"'
}</pre><p><strong>Note</strong>: this step is optional. If you wish you can skip it and your plugin will work perfectly fine, just without any user set configuration.</p><p>We already have the most essential part of enabling user set options in place in our plugin. In our <code class="inline">module.exports</code> line you’ll notice an <code class="inline">options</code> argument is being passed. </p><pre class="brush: javascript noskimlinks noskimwords">module.exports = postcss.plugin('myplugin', function (options) {</pre><p>We’ll receive any user options a user sets through this.</p><p>You’ll also see we have the line:</p><pre class="brush: javascript noskimlinks noskimwords">options = options || {};</pre><p>This checks to see if <code class="inline">options</code> has any value, and if it doesn’t, sets it to an empty object. This makes sure we don’t get any errors when we start working with <code class="inline">options</code> that might come from it being undefined.</p><p>To get started, we’re going to install Underscore.js into our project, as we’ll be using its handy <a href="http://underscorejs.org/#extend" rel="external" target="_blank">extend()</a> method. Run this command to install it into the plugin you’re building:</p><pre class="brush: bash noskimlinks noskimwords">npm install underscore --save</pre><p>Now load Underscore into your plugin by adding an <code class="inline">_</code> variable to require it, under your existing <code class="inline">postcss</code> variable:</p><pre class="brush: javascript noskimlinks noskimwords">var postcss = require('postcss');
var _ = require('underscore');</pre><p>Next what we’re going to do is take the <code class="inline">fontstacks_config</code> object we already created inside the plugin, and “extend” it with any font stacks the user has set through their options configuration.</p><p>Add this code directly under the <code class="inline">options = options || {};</code> line:</p><pre class="brush: javascript noskimlinks noskimwords"> // Extend the default fontstacks_config option with any custom fontstacks set in the plugin's options
fontstacks_config = _.extend(fontstacks_config, options.fontstacks);</pre><p>The <code class="inline">fontstacks</code> option that has been set by the user is represented by <code class="inline">options.fontstacks</code>.</p><p>By using Underscore’s <code class="inline">extend()</code> method, all the font stacks in <code class="inline">options.fontstacks</code> are added to those already in <code class="inline">fontstacks_config</code>. Wherever there is a matching key, the value from <code class="inline">options.fontstacks</code> will overwrite the one in <code class="inline">fontstacks_config</code>. This allows users to redefine any existing font stacks.</p><p>In your Gulpfile or Gruntfile, set a <code class="inline">fontstacks</code> option and pass a new font stack as well as redefining an existing one:</p><pre class="brush: javascript noskimlinks noskimwords">/* Gulpfile */
var processors = [
myplugin({
fontstacks: {
'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif',
'Arial': 'Arial, "Comic Sans"'
}
})
];
/* Gruntfile */
processors: [
require('postcss-myplugin')({
fontstacks: {
'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif',
'Arial': 'Arial, "Comic Sans"'
}
})
]</pre><p>Now add some extra CSS to your “src/style.css” file so we can test the new font stack we just added via our options:</p><pre class="brush: css noskimlinks noskimwords">h2 {
font-family: "Droid Sans", fontstack("Extra Stack");
}</pre><p>Recompile your CSS and you should see that your 'Arial' font stack now has different output, and that your 'Extra Stack' font stack has output correctly:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-family: "Open Sans", Arial, "Comic Sans";
}
h2 {
font-family: "Droid Sans", "Extra Stack", "Moar Fonts", Extra, serif;
}</pre><h2>Your Completed Plugin</h2><p>That’s it! You’re all done. You’ve completed your first PostCSS plugin.</p><p>Here’s <a href="https://github.com/tutsplus/postcss-deep-dive-create-your-own-plugin/blob/master/postcss-myplugin/index.js" target="_self">the entire thing on GitHub</a> should you need to compare your code to it for reference.</p><h2>Let’s Recap</h2><p>You’ve just created an entire PostCSS plugin, and I hope some ideas are springing into your mind about other plugins you’d love to make. Maybe there’s that one little thing that’s always bugged you when writing CSS, and perhaps now you can come up with your own solution to get rid of it for good. Or maybe there’s something extra you really think CSS ought to have out of the box—well, now you can add it in for yourself!</p><p>To sum up what we’ve covered:</p><ul>
<li>Start developing a new plugin by setting up a Gulp or Grunt project to work in.</li>
<li>Create a new node module inside your project, which will become your plugin.</li>
<li>Load your new plugin into your project.</li>
<li>Add some test CSS in the syntax you want your plugin to use.</li>
<li>Use methods from the <a href="https://github.com/postcss/postcss/blob/master/docs/api.md" rel="external" target="_blank">PostCSS API</a> to scan through a stylesheet.</li>
<li>Locate instances of your plugin's syntax being used.</li>
<li>Write JavaScript and use the <a href="https://github.com/postcss/postcss/blob/master/docs/api.md" rel="external" target="_blank">PostCSS API</a> to make the appropriate transformations (and/or additions) to the original code and send it into the processed CSS.</li>
</ul><h2>For TypeScript Users</h2><p>As part of the <a href="https://github.com/postcss/postcss/releases/tag/5.0.0" rel="external" target="_blank">5.0 release of PostCSS</a>, Jed Mao has contributed a great set of TypeScript definitions that can help a great deal with plugin development through providing autocompletion and inline documentation as you type.</p><figure class="post_image"><img alt="TypeScript definitions" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24605/image/typescript.png"></figure><p>If you find yourself getting into PostCSS plugin development, this is really something worth looking at incorporating into your workflow. I myself am not a dab TypeScript hand, but am going to jump into coding with it anyway, almost purely so I can leverage this functionality.</p><p>If you’d like to try this out you don’t need to be on Windows or using Visual Studio, as you can use the free, open-source <a href="https://code.visualstudio.com/" rel="external" target="_blank">Visual Studio Code</a>, which runs on Windows, Mac and Linux and is <a href="http://thenextweb.com/apps/2015/04/30/microsofts-cross-platform-visual-studio-code-app-is-based-on-githubs-atom-editor/" rel="external" target="_blank">built on Electron</a>, the same shell that powers <a href="https://atom.io/" rel="external" target="_blank">Atom Editor</a>.</p><p>For an example of how to incorporate these TypeScript definitions into your project, check out the <a href="https://github.com/jedmao/postcss-font-pack/blob/master/lib/plugin.ts" rel="external" target="_blank">postcss-font-pack</a> plugin. Fork it and have a play in Visual Studio Code to see how the autocompletion and inline documentation works.</p><h2>PostCSS Deep Dive: Wrapping Up</h2><p>Thanks very much for following along with this PostCSS Deep Dive series. I hope you enjoyed reading it as much as I enjoyed creating it! More importantly, I hope you have a head full of ideas on how you can put PostCSS to work in your daily web development life.</p><p>PostCSS really is an incredible new addition to the front-end world, as the way it facilitates plugins opens up doors to possibilities we have never had before in CSS development. The range of plugins that are available right now is already enough to completely reshape a person’s daily workflows, and that’s just with what has been created in the space of a couple of years. </p><p>I would suggest that PostCSS has yet to peak, and that as it begins to be something the majority of CSS developers at least know about, if not swear by, we’ll see it really come into its stride. And with more front-end developers coming on board, we’ll see more contributions to the plugin ecosystem, adding new plugins and helping to build up existing ones.</p><p>With those plugins being free to cater to any type of CSS transformation a developer can dream up, the future of PostCSS is very intriguing indeed. I look forward to being a part of it, and hope you will come along for the ride too!</p>2015-11-10T14:29:30.000Z2015-11-10T14:29:30.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24603PostCSS Deep Dive: Miscellaneous Goodies<p>Throughout this series we’ve been through many different categories of PostCSS plugins, offering all kinds of different advantages for your CSS development. But some of the very best PostCSS plugins don’t fit into the categories we’ve covered in our previous series entries.</p><p>In this tutorial you’re going to learn about five of these “miscellaneous goodies”. We’ll cover:</p><ul>
<li>Generating grids with <a href="https://github.com/corysimmons/lost" rel="external" target="_blank">Lost</a>
</li>
<li>Seeing how your designs look to colorblind people with <a href="https://github.com/btholt/postcss-colorblind">postcss-colorblind</a>
</li>
<li>Converting px units to rem with <a href="https://github.com/cuth/postcss-pxtorem">postcss-pxtorem</a>
</li>
<li>Auto-generating an RTL version of your stylesheet with <a href="https://github.com/MohammadYounes/rtlcss">rtlcss</a>
</li>
<li>Auto-generating a style guide with <a href="https://github.com/morishitter/postcss-style-guide">postcss-style-guide</a>
</li>
</ul><p>Let's begin!</p><h2>Setup Your Project</h2><p>As ever, 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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don’t want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/postcss-deep-dive-miscellaneous-goodies/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.</p><h2>Install Plugins</h2><p>Now we’ll need to install five plugins into your project. Whether you’re using Gulp or Grunt, run the following command inside your project folder to install the plugins we’ll be using:</p><pre class="brush: bash noskimlinks noskimwords">npm install lost postcss-colorblind postcss-pxtorem postcss-style-guide --save-dev</pre><p>As well as these five we’ll also be using rtlcss, but as it works a little differently to other PostCSS plugins we’ll be using it via its corresponding Gulp or Grunt plugins. </p><p>If using Gulp, install gulp-rtlcss with the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install gulp-rtlcss gulp-rename --save-dev</pre><p>And if using Grunt install grunt-rtlcss with the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install grunt-rtlcss --save-dev</pre><p>Now we’re ready to load the plugins into your project.</p><h3>Load Plugins via Gulp</h3><p>If you’re using Gulp, add these variables under the variables already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var lost = require('lost');
var colorblind = require('postcss-colorblind');
var pxtorem = require('postcss-pxtorem');
var styleGuide = require('postcss-style-guide');
var rtlcss = require('gulp-rtlcss');
var rename = require('gulp-rename');</pre><p>Now add each of those new variable names into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
lost,
// colorblind,
pxtorem,
styleGuide
];</pre><p><strong>Note</strong>: <code class="inline">colorblind</code> is commented out, which will be explained later.</p><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load Plugins via Grunt</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('lost')(),
// require('postcss-colorblind')(),
require('postcss-pxtorem')(),
require('postcss-style-guide')()
]</pre><p><strong>Note</strong>: <code class="inline">require('postcss-colorblind')(),</code> is commented out, which will be explained later.<br></p><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h2>Generate Grids with Lost</h2><p><a href="https://github.com/corysimmons/lost" rel="external" target="_blank">Lost</a> is a completely PostCSS based grid generation system by <a href="http://tutsplus.com/authors/cory-simmons" rel="external" target="_blank">Cory Simmons</a>, the creator of Jeet, another very successful grid system written in Stylus. It has a long list of impressive features, yet its deployment is very straight forward.</p><p>Start by creating a file named “index.html” in your “dest” folder. We’ll be setting up a basic grid layout in this file. Add the following code to it:</p><pre class="brush: html noskimlinks noskimwords">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="row"&gt;
&lt;div class="main"&gt;
&lt;h1&gt;Main Area&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="sidebar"&gt;
&lt;h1&gt;Sidebar&lt;/h1&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>Then add this code to your “src/style.css” to setup a basic two column grid layout, with a main area column and sidebar column:</p><pre class="brush: css noskimlinks noskimwords">@lost gutter 1.618rem;
.row {
lost-center: 75rem;
}
.main {
lost-column: 3/5;
}
.sidebar {
lost-column: 2/5;
}</pre><p>Let’s break down what we’ve done here.</p><p>First, we’ve use a <code class="inline">@lost</code> at-rule to set our own value for one of Lost’s options: gutter size. By default gutters (gaps between columns) are <code class="inline">30px</code>. I always like to use <code class="inline">1.618rem</code> for spacing in designs, so I’ve set that to be the new gutter size with the line <code class="inline">@lost gutter 1.618rem;</code>.</p><p>Next, we’ve setup a <code class="inline">.row</code> class that we’ll wrap around our columns. This only requires using the property <code class="inline">lost-center</code> and specifying a width for the row. The plugin will take care of setting a <code class="inline">max-width</code> on the class, centering it, and clearing it.</p><p>After that, in the <code class="inline">.main</code> and <code class="inline">.sidebar</code> classes, we’ve created our columns. </p><p>Lost doesn’t restrict you to working with a predetermined number of columns like twelve or sixteen; you can have any number of columns you want. Column widths are determined by using the property <code class="inline">lost-column</code> and setting a fraction as the value. In our code the <code class="inline">.main</code> class uses a setting of <code class="inline">3/5</code> so it will take up 3 of 5 columns, and the <code class="inline">.sidebar</code> uses <code class="inline">2/5</code> so it will take 2 of 5 columns.</p><p>Compile your file and in your “dest/style.css” file you should now see this code:</p><pre class="brush: css noskimlinks noskimwords">.row {
*zoom: 1;
max-width: 75rem;
margin-left: auto;
margin-right: auto;
}
.row:before {
content: '';
display: table;
}
.row:after {
content: '';
display: table;
clear: both;
}
.main {
width: calc(99.99% * 3/5 - (1.618rem - 1.618rem * 3/5));
}
.main:nth-child(n) {
float: left;
margin-right: 1.618rem;
clear: none;
}
.main:last-child {
margin-right: 0;
}
.main:nth-child(5n) {
margin-right: 0;
}
.main:nth-child(5n + 1) {
clear: left;
}
.sidebar {
width: calc(99.99% * 2/5 - (1.618rem - 1.618rem * 2/5));
}
.sidebar:nth-child(n) {
float: left;
margin-right: 1.618rem;
clear: none;
}
.sidebar:last-child {
margin-right: 0;
}
.sidebar:nth-child(5n) {
margin-right: 0;
}
.sidebar:nth-child(5n + 1) {
clear: left;
}</pre><p>And when viewed in a browser, your “dest/index.html” file should now present a two column layout like this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/lost_added.png"></figure><p>It’s a little hard to see exactly what’s going on with our grid here, which is the reason Lost also provides <code class="inline">lost-utility: edit;</code> to highlight your grid for easy visualization during development. </p><p>Add this to each of the classes we’ve created so far:</p><pre class="brush: css noskimlinks noskimwords">.row {
lost-center: 75rem;
lost-utility: edit;
}
.main {
lost-column: 3/5;
lost-utility: edit;
}
.sidebar {
lost-column: 2/5;
lost-utility: edit;
}</pre><p>Now when you recompile and refresh your page you should see your grid highlighted like this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/lost_edit_mode.png"></figure><p>Let’s make that all a little clearer to see again with some extra styling (which will also help us with later sections in this tutorial). Update your “src/style.css” file to the following, adding a couple of extras like padding inside the columns and a few background and text colors:</p><pre class="brush: css noskimlinks noskimwords">@lost gutter 1.618rem;
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
font-family: "Open Sans";
}
html {
padding: 0;
}
body {
padding: 1.618rem;
background: #16a085;
}
.row {
lost-center: 75rem;
}
.main, .sidebar {
padding: 1.618rem;
min-height: 500px;
}
.main {
lost-column: 3/5;
background: white;
color: #232323;
}
.sidebar {
lost-column: 2/5;
background: #2c3e50;
color: white;
}</pre><p>Compile your CSS again and reload your page and you should now have a classic two column layout like this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/lost_colored.png"></figure><p>What we’ve covered here just skims the surface of what can be done with Lost, so be sure to read about all the rest of the features at: <a href="https://github.com/corysimmons/lost">https://github.com/corysimmons/lost</a></p><h2>See Through the Eyes of the Colorblind</h2><p>Color blindness effects a larger portion of your site’s visitors than you might realize. For example, the most common <a href="https://en.wikipedia.org/wiki/Color_blindness#Types" rel="external" target="_blank">type of color blindness</a> is deuteranomaly, effecting 6% of all males and 0.4% of females. To put that in perspective, it’s estimated IE9 and IE10 combined are used by <a href="http://www.sitepoint.com/browser-trends-april-2015-statcounter-vs-netmarketshare/" rel="external" target="_blank">around 4%</a> of all web traffic. One might suggest that if we can put a significant amount of time into supporting specific browsers, we can put an equal measure of time into supporting people.</p><p>The <a href="https://github.com/btholt/postcss-colorblind">postcss-colorblind</a> plugin by Brian Holt helps immeasurably in assessing how accessible a design is for people with various forms of color blindness, as it allows you to see for yourself how your color schemes would look if you had the same visual perception. It allows you to generate versions of your stylesheet that simulate eight different kinds of color blindness. Let’s see how you can use it.</p><h3>Add Some Extra Colors</h3><p>First, we’ll add some extra colors to our design so far to help us more clearly see the effect of the different stylesheets we’re about to generate. We’ll add five “metro style” tiles, by adding the following html below the row we already have in our “dest/index.htm” file:</p><pre class="brush: html noskimlinks noskimwords">&lt;div class="row"&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;/div&gt;</pre><p>Now add the following code to your “src/style.css” file to style these tiles with five different colors:</p><pre class="brush: css noskimlinks noskimwords">.row {
margin-bottom: 1.618rem;
}
.tile {
lost-column: 1/5;
padding: 3.75rem 1.618rem;
text-align: center;
font-size: 1.25rem;
color: white;
}
.tile:nth-of-type(1) {
background: #f39c12;
}
.tile:nth-of-type(2) {
background: #c0392b;
}
.tile:nth-of-type(3) {
background: #8e44ad;
}
.tile:nth-of-type(4) {
background: #2980b9;
}
.tile:nth-of-type(5) {
background: #d35400;
}</pre><p>After compilation, you should see your file now looks like this in a browser:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/default_colors.png"></figure><h3>Generate Colorblind Simulations</h3><p>You may have noticed that when we setup our <code class="inline">processors</code> array earlier the entry for <code class="inline">colorblind</code> was commented out. That’s because as soon as the plugin is active it will apply colorblind simulation to your stylesheet, so you don’t want to turn it on until you’re ready to use it. Uncomment it in the <code class="inline">processors</code> array now.</p><p>To simulate any of the eight types of colorblindness, pass the option <code class="inline">method</code> for this plugin in your Gulpfile or Gruntfile, along with the name of the type of colorblindness you want to check on.</p><p>For example, to simulate deuteranomaly set this option:</p><pre class="brush: plain noskimlinks noskimwords">/* Gulpfile */
colorblind({method: 'deuteranomaly'}),
/* Gruntfile */
require('postcss-colorblind')({method: 'deuteranomaly'})</pre><p>Now recompile your stylesheet and refresh your page and you will see your design as a person with deuteranomaly does:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/deuteranomaly.png"></figure><p>You’ll notice the colors look notably different. A person with deuteranomaly sees red and green differently, so while you’ll notice the blue is almost the same, the reds and greens are quite different.</p><p>To visualize protanopia set this option:</p><pre class="brush: plain noskimlinks noskimwords">/* Gulpfile */
colorblind({method: 'protanopia'}),
/* Gruntfile */
require('postcss-colorblind')({method: 'protanopia'})</pre><p>Recompile your stylesheet and now you’ll see this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/protanopia.png"></figure><p>A person with protanopia essentially does not see red at all, and sees green in a different way. You’ll notice again that the strong blues are not too heavily effected, but purple has become pure blue, and the remaining colors have become variations of the same yellowish brownish colors. It has become very difficult to distinguish the red and two orange colored tiles from one another.</p><p>This ability to generate all different types of colorblind simulations is incredibly insightful, and helps us to ensure the color schemes we have chosen don’t rely on perception of a particular hue and are thereby accessible to all.</p><p>Read more about postcss-colorblind at: <a href="https://github.com/btholt/postcss-colorblind">https://github.com/btholt/postcss-colorblind</a></p><h2>Convert px Units to rem</h2><p>In almost all designs, there are <a href="http://webdesign.tutsplus.com/tutorials/comprehensive-guide-when-to-use-em-vs-rem--cms-23984" rel="external" target="_blank">very good reasons</a> for the <code class="inline">rem</code> unit to play a prominent role. However it is difficult to think in <code class="inline">rem</code> units, and much easier to think in <code class="inline">px</code> units when creating layouts. The <a href="https://github.com/cuth/postcss-pxtorem">postcss-pxtorem</a> plugin helps with this speedbump, by automatically converting <code class="inline">px</code> units to <code class="inline">rem</code> units.</p><p>The plugin uses a white list of properties to which it applies, so by default <code class="inline">px</code> units will be converted to <code class="inline">rem</code> when used on:</p><ul>
<li>font</li>
<li>font-size</li>
<li>line-height</li>
<li>letter-spacing</li>
</ul><p>You can add extra properties to this white list by setting a <code class="inline">prop_white_list</code> option. Update your Gulpfile or Gruntfile to add the <code class="inline">width</code> property like so:</p><pre class="brush: javascript noskimlinks noskimwords">/* Gulpfile */
pxtorem({
prop_white_list: ['width', 'font', 'font-size', 'line-height', 'letter-spacing']
}),
/* Gruntfile */
require('postcss-pxtorem')({
prop_white_list: ['width', 'font', 'font-size', 'line-height', 'letter-spacing']
}),</pre><p>Now add the following code to your “src/style.css” file so we can test the conversion process:</p><pre class="brush: css noskimlinks noskimwords">.convert_this {
width: 500px;
font-size: 18px;
}</pre><p>Compile your file and in your “dest/style.css” file you should now see the resulting <code class="inline">rem</code> values:</p><pre class="brush: css noskimlinks noskimwords">.convert_this {
width: 31.25rem;
font-size: 1.125rem;
}</pre><p>Read more about postcss-pxtorem at: <a href="https://github.com/cuth/postcss-pxtorem">https://github.com/cuth/postcss-pxtorem</a></p><h2>Generate a RTL Version of Your Stylesheet</h2><p>If you are <a href="http://webdesign.tutsplus.com/articles/tips-for-designing-and-building-a-multilingual-website--cms-24708" target="_self">catering to a global audience</a>, you may need to provide support for scripts that are read from right to left rather than left to right, such as Arabic and Hebrew for example. When the orientation of script is flipped, so too should the layout of your site so the entire design makes sense for those who look at the right side of the screen first.</p><p>The <a href="https://github.com/MohammadYounes/rtlcss">rtlcss</a> plugin by Mohammad Younes makes the process of creating a right-to-left layout much easier, as it can automatically scan your stylesheet and convert its orientation, swapping the word “left” for “right” and vice versa.</p><p>This plugin actually works a little differently to other PostCSS plugins, in that we can’t add it to our <code class="inline">processors</code> array. Instead, during our project setup we installed the <a href="https://github.com/jjlharrison/gulp-rtlcss" rel="external" target="_blank">Gulp</a> and <a href="https://github.com/MohammadYounes/grunt-rtlcss" rel="external" target="_blank">Grunt</a> plugins for rtlcss, and we’re going to setup separate tasks to execute it.</p><p>If using Gulp, add this code to your Gulpfile:</p><pre class="brush: javascript noskimlinks noskimwords">gulp.task('rtl', function () {
return gulp.src('./dest/style.css')
.pipe(rtlcss())
.pipe(rename({ suffix: '-rtl' }))
.pipe(gulp.dest('./dest'));
});</pre><p>If using Grunt, add this line after your existing <code class="inline">grunt.loadNpmTasks</code> line:</p><pre class="brush: javascript noskimlinks noskimwords">grunt.loadNpmTasks('grunt-rtlcss');</pre><p>Then add a comma <code class="inline">,</code> after your <code class="inline">postcss</code> task, and paste in this new <code class="inline">rtlcss</code> task:</p><pre class="brush: javascript noskimlinks noskimwords">rtlcss: {
'default':{
dest : 'dest/style-rtl.css',
src : 'dest/style.css'
}
}</pre><p>Now, if using Gulp run the command <code class="inline">gulp rtl</code>, and if using Grunt run the command <code class="inline">grunt rtlcss</code> to generate a right-to-left stylesheet named “style-rtl.css” in your “dest” folder.</p><p>Edit your “dest/index.html” file to load “style-rtl.css” instead of “style.css”, refresh your site, and you should see your layout has been flipped around:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/rtld.png"></figure><p>You’ll notice the text is still left aligned, but this can be easily remedied by just adding <code class="inline">text-align: left;</code> in your default stylesheet, which rtlcss will convert to <code class="inline">text-align: right;</code>.</p><p>Read more about rtlcss and its Gulp and Grunt counterparts at:</p><ul>
<li><a href="https://github.com/MohammadYounes/rtlcss">https://github.com/MohammadYounes/rtlcss</a></li>
<li><a href="https://github.com/jjlharrison/gulp-rtlcss">https://github.com/jjlharrison/gulp-rtlcss</a></li>
<li>
<a href="https://github.com/MohammadYounes/grunt-rtlcss">https://github.com/MohammadYounes/grunt-rtlcss</a><br>
</li>
</ul><h2>Generate a Style Guide</h2><p>The <a href="https://github.com/morishitter/postcss-style-guide">postcss-style-guide</a> plugin is a fantastic tool created by Masaaki Morishita. It allows you to generate a styleguide automatically based on your stylesheet. All you have to do is add some comments to your CSS, and those comments will be parsed as <a href="http://daringfireball.net/projects/markdown/" rel="external" target="_blank">Markdown</a> and used to populate your styleguide.</p><p>The first thing we’re going to do is configure a couple of options for our styleguide. We’re going to set the name of our project so it can be displayed in the header of the styleguide, and we’re also going to use a custom theme named <a href="https://github.com/seka/psg-theme-1column" rel="external" target="_blank">1column</a>.</p><p>To install the custom theme we’ll be using into your project, run the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install psg-theme-1column --save-dev</pre><p>Now update your Gulpfile or Gruntfile to pass a <code class="inline">name</code> and <code class="inline">theme</code> options as follows:</p><pre class="brush: javascript noskimlinks noskimwords">/* Gulpfile */
styleGuide({
name: 'Auto Style Guide',
theme: '1column'
})
/* Gruntfile */
require('postcss-style-guide')({
name: 'Auto Style Guide',
theme: '1column'
})</pre><p>The way postcss-styleguide works is that it will look for your comments in your stylesheet and turn each one it finds into a styleguide entry. It will assume any comment relates to the CSS that follows it, all the way through to another comment or the end of the document.</p><p>For this reason, any CSS that you want to showcase in your styleguide should be moved to the bottom of your stylesheet. We’re going to have our colored tiles appear in the styleguide, as well as an <code class="inline">h1</code> element, so we’ll need both of those to be at the end of our document.</p><p>Start by moving all the classes that effect our tiles down to the bottom of your stylesheet; that’s the <code class="inline">.tile</code> class and the five <code class="inline">.tile:nth-of-type()</code> styles. Then also add a little code to control <code class="inline">h1</code> elements so the bottom of your stylesheet looks like this (the <em>.tile:nth-of-type() </em>styles aren’t shown to save space):</p><pre class="brush: css noskimlinks noskimwords">h1 { font-size: 42px; }
.tile {
lost-column: 1/5;
padding: 3.75rem 1.618rem;
text-align: center;
font-size: 1.25rem;
color: white;
}</pre><p>Now we can add in some comments to describe these styles. Any html added in these comments will be rendered as html in the styleguide, and the CSS that follows a comment will appear in a display box.</p><p>Add some comments to your stylesheet describing the <code class="inline">h1</code> style and the <code class="inline">.tile</code> class, and including some example html, so you end up with the following:</p><pre class="brush: css noskimlinks noskimwords">/*
This is the h1 style
&lt;h1&gt;Heading 1&lt;/h1&gt;
*/
h1 { font-size: 42px; }
/*
These use the .tile class
&lt;div class="row"&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;div class="tile"&gt;This is a Tile&lt;/div&gt;
&lt;/div&gt;
*/
.tile {
lost-column: 1/5;
padding: 3.75rem 1.618rem;
text-align: center;
font-size: 1.25rem;
color: white;
}</pre><p>Now compile your stylesheet, look in your project’s root folder and open the “styleguide.html” file you find there in a browser:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/autostyleguide.png"></figure><p>Hey presto, instant styleguide!</p><p>At the moment it looks a little funky because it has picked up the green body background color from our stylesheet. What we want is for our content to be on a white background, and we can get the styleguide to pick up some other code from our stylesheet to make this happen.</p><p>The central area of this styleguide template uses a <code class="inline">section</code> element, so <em>above</em> the comment describing your <code class="inline">h1</code> element, add this code:</p><pre class="brush: css noskimlinks noskimwords">section {
padding: 1rem;
background: white;
}</pre><p>Recompile your code, refresh your styleguide, and you’ll see it’s now making use of the styling we just added to <code class="inline">section</code> elements and looks like this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24603/image/sgwhiteadded.png"></figure><p>There, much better.</p><p>Read more about postcss-style-guide at: <a href="https://github.com/morishitter/postcss-style-guide">https://github.com/morishitter/postcss-style-guide</a></p><h2>Let’s Recap</h2><p>Summing up everything we’ve covered above:</p><ul>
<li>The <a href="https://github.com/corysimmons/lost">Lost</a> plugin allows you to create flexible grids with just a few properties, with lots of extra functionality available too should you need it.</li>
<li>The <a href="https://github.com/btholt/postcss-colorblind">postcss-colorblind</a> plugin lets you see for yourself how your designs look to people with any of eight different types of colorblindness.<br>
</li>
<li>The <a href="https://github.com/cuth/postcss-pxtorem">postcss-pxtorem</a> plugin enables you to write code using <code class="inline">px</code> units but have them automatically converted to <code class="inline">rem</code> units during processing.<br>
</li>
<li>The <a href="https://github.com/MohammadYounes/rtlcss">rtlcss</a> plugin automatically generates right-to-left stylesheets by scanning your code for the word “right” and replacing it with “left”, and vice versa.<br>
</li>
<li>The <a href="https://github.com/morishitter/postcss-style-guide">postcss-style-guide</a> plugin automatically generates a styleguide, based on comments added to your stylesheet.<br>
</li>
</ul><h2>Coming Next: Make Your Own Plugin</h2><p>In the next and final installation of this PostCSS Deep Dive you’ll learn how to unlock one of the biggest advantages that PostCSS offers; that being the ability to use it to create any type of functionality you want.</p><p>You’ll learn how to make your own basic plugin, and from that basis hopefully you’ll go on to make many more plugins for whatever need might arise in the future.</p><p>I’ll see you in the final tutorial!</p>2015-11-04T14:10:25.000Z2015-11-04T14:10:25.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24602PostCSS Deep Dive: Shortcuts and Shorthand<p>So far we’ve used PostCSS to do things like optimizing stylesheets, adding functionality for preprocessing, and generating certain class naming conventions, but how can it help just writing plain old CSS?</p><p>There are so many little bits of code the average web designer types out thousands of times through the course of their career, and if you can gain just a little bit of time back on each one it adds up to a lot in the end.</p><p>In this tutorial we’re going to use PostCSS to cut down on every day code typing time via a series of shortcuts and shorthand additions. Let’s begin!</p><h2>Setup Your Project</h2><p>You’ll be familiar with this process by now, but the first thing you’ll need to do is setup your project to use either Gulp or Grunt. 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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/postcss-deep-dive-shortcuts-and-shorthand/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.</p><h2>Install Plugins</h2><p>For this tutorial we’ll be installing several plugins, each one handling a different type of shortcut or shorthand.</p><p>Whether you’re using Gulp or Grunt, run the following command inside your project folder to install the plugins we’ll be using:</p><pre class="brush: bash noskimlinks noskimwords">npm install postcss-alias postcss-crip postcss-font-magician postcss-triangle postcss-circle postcss-all-link-colors postcss-center postcss-clearfix postcss-position postcss-size postcss-verthorz postcss-color-short --save-dev</pre><p>Now we’re ready to load the plugins into your project.</p><h3>Load Plugins via Gulp</h3><p>If you’re using Gulp, add these variables under the variables already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var alias = require('postcss-alias');
var crip = require('postcss-crip');
var magician = require('postcss-font-magician');
var triangle = require('postcss-triangle');
var circle = require('postcss-circle');
var linkColors = require('postcss-all-link-colors');
var center = require('postcss-center');
var clearfix = require('postcss-clearfix');
var position = require('postcss-position');
var size = require('postcss-size');
var verthorz = require('postcss-verthorz');
var colorShort = require('postcss-color-short');</pre><p>Now add each of those new variable names into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
alias,
crip,
magician,
triangle,
circle,
linkColors,
center,
clearfix,
position,
size,
verthorz,
colorShort
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load Plugins via Grunt</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('postcss-alias')(),
require('postcss-crip')(),
require('postcss-font-magician')(),
require('postcss-triangle')(),
require('postcss-circle')(),
require('postcss-all-link-colors')(),
require('postcss-center')(),
require('postcss-clearfix')(),
require('postcss-position')(),
require('postcss-size')(),
require('postcss-verthorz')(),
require('postcss-color-short')()
]</pre><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><p>Alright, now your plugins are all installed let’s learn how to use them for CSS shortcuts and shorthand.</p><h2>Use Shorthand for Properties</h2><p>There are a lot of properties we have to type over and over <em>and over</em> again in CSS. Sure, the time it takes to type a handful of characters once is very small, but over years of development it all adds up. We’re going to look here at two plugins that allow you to trim those properties down to shorthand versions to you can get a quick and smooth flow going as you hammer out your CSS.</p><h3>Define Your Own Shorthand</h3><p>The <a href="https://github.com/seaneking/postcss-alias">postcss-alias</a> plugin by Sean King allows you to define your own shorthand, or “aliases”, for any properties you want to abbreviate. This gives you a way to make sure the shorthand you use fits with the way your mind works and is hence easy for you to remember.</p><p>To define some aliases add an at-rule at the top of your stylesheet with the syntax <code class="inline">@alias {...}</code>. Then inside the at-rule setup your aliases by adding <code class="inline">alias-name: property-name;</code>. </p><p>Add the following example to your “src/style.css” file, which will setup aliases for the <code class="inline">border-size</code>, <code class="inline">border-style</code> and <code class="inline">border-color</code> properties:</p><pre class="brush: css noskimlinks noskimwords">@alias {
bsz: border-size;
bst: border-style;
bcl: border-color;
}</pre><p>Then add this code to test out using the new aliases:</p><pre class="brush: css noskimlinks noskimwords">.set_border {
bsz: 1px;
bst: solid;
bcl: #ccc;
}</pre><p>Compile your file, and in your “dest/style.css” file you should now see:</p><pre class="brush: css noskimlinks noskimwords">.set_border {
border-size: 1px;
border-style: solid;
border-color: #ccc;
}</pre><p>Read more about postcss-alias at: <a href="https://github.com/seaneking/postcss-alias">https://github.com/seaneking/postcss-alias</a></p><h3>Plug ‘n’ Play Shorthand</h3><p>If you want to use a lot of property shorthands, but you don’t want to go through the steps of defining each one yourself, you can check out the plugin <a href="https://github.com/johnie/postcss-crip">postcss-crip</a> by Johnie Hjelm which has hundreds of property abbreviations ready for plugin and play use.</p><p>For example, add the following code to your “src/style.css” file, which contains shorthand for the <code class="inline">margin-top</code>, <code class="inline">margin-right</code>, <code class="inline">margin-bottom</code> and <code class="inline">margin-left</code> properties: </p><pre class="brush: css noskimlinks noskimwords">.crip_shorthand {
mt: 1rem;
mr: 2rem;
mb: 3rem;
ml: 4rem;
}</pre><p>Compile your code and you should see the expanded properties appear in your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.crip_shorthand {
margin-top: 1rem;
margin-right: 2rem;
margin-bottom: 3rem;
margin-left: 4rem;
}</pre><p>Read more about postcss-crip at: <a href="https://github.com/johnie/postcss-crip">https://github.com/johnie/postcss-crip</a></p><p>And see the full list of property abbreviations at: <a href="https://github.com/johnie/crip-css-properties">https://github.com/johnie/crip-css-properties</a></p><h2>Output @font-face in One Line</h2><p>The <a href="https://github.com/jonathantneal/postcss-font-magician">postcss-font-magician</a> plugin by Jonathan Neal very much lives up to its name. It allows you to use custom fonts via a simple <code class="inline">font-family</code> rule as though you were using a standard font, and the font will just magically work.</p><p>Add the following code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">body {
font-family: "Indie Flower";
}</pre><p>That’s it. That’s all it takes to make use of postcss-font-magician. No special syntax, just use the font name as you would any other.</p><p>In this case, the <a href="https://www.google.com/fonts/specimen/Indie+Flower" rel="external" target="_blank">Indie Flower</a> font is one that I’ve selected from the Google Fonts library. I haven’t added any custom font files to my project, so the plugin will see that and instead go check to see if my specified font is available from Google Fonts. When it finds that it is available, it will create the appropriate <code class="inline">@font-face</code> code completely automatically.</p><p>Compile your file then look at your “dest/style.css” file, where you’ll see this code has been added in:</p><pre class="brush: plain noskimlinks noskimwords">@font-face {
font-family: "Indie Flower";
font-style: normal;
font-weight: 400;
src: local("Indie Flower"),local(IndieFlower),
url(//fonts.gstatic.com/s/indieflower/v7/10JVD_humAd5zP2yrFqw6nZ2MAKAc2x4R1uOSeegc5U.eot?#) format("eot"),
url(//fonts.gstatic.com/s/indieflower/v7/10JVD_humAd5zP2yrFqw6ugdm0LZdjqr5-oayXSOefg.woff2) format("woff2"),
url(//fonts.gstatic.com/s/indieflower/v7/10JVD_humAd5zP2yrFqw6nhCUOGz7vYGh680lGh-uXM.woff) format("woff");
}</pre><p>You can check that the font is loading correctly by creating a new file in your “dest” folder named “index.html” and adding this code to it:</p><pre class="brush: html noskimlinks noskimwords">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Test Heading&lt;/h1&gt;
&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque pretium bibendum nisl. Mauris eget orci eget nisi tristique lobortis. Pellentesque rutrum id ligula quis tempus. Vivamus tempus, justo at semper volutpat, lorem justo tincidunt urna, in mattis lorem dolor condimentum diam. Ut dapibus nunc auctor felis viverra posuere. Aenean efficitur efficitur nisi. Vivamus leo felis, semper quis rutrum eu, eleifend eu quam.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>For the fonts to load you’ll need to view this file via an <code class="inline">http://</code> address, rather than a <code class="inline">file://</code> address, so either upload the file to a web host or use an app like <a href="https://prepros.io/" rel="external" target="_blank">Prepros</a> to create a live preview.</p><p>You should see the Indie Flower font applied to all your text, like so:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24602/image/fontadded.png"></figure><p>Read more about postcss-font-magician here: <a href="https://github.com/jonathantneal/postcss-font-magician">https://github.com/jonathantneal/postcss-font-magician</a></p><h2>Create CSS Shapes</h2><p>If you’ve ever used pure CSS to create shapes, you’ll know it can be a great way to include things like circles and triangles into your designs, but that it can also be quite tricky. Particularly in the case of triangles, figuring out what code you need to get a shape oriented in the right direction at the right size can feel somewhat counter intuitive.</p><p>That’s where the <a href="https://github.com/jedmao/postcss-circle">postcss-circle</a> and <a href="https://github.com/jedmao/postcss-triangle">postcss-triangle</a> plugins by Jed Mao come to the rescue. Both plugins create a simplified syntax, and an intuitive way of creating circles and triangles with pure CSS.</p><h3>Add a Circle</h3><p>To create a circle, use the syntax <code class="inline">circle: size color;</code>. Add the following code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.circle {
circle: 8rem #c00;
}</pre><p>Compile it and you’ll see the following code added to your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.circle {
border-radius: 50%;
width: 8rem;
height: 8rem;
background-color: #c00;
}</pre><p>Now add this HTML to the “dest/index.html” file you created in the last section:</p><pre class="brush: html noskimlinks noskimwords">&lt;div class="circle"&gt;&lt;/div&gt;</pre><p>Take a fresh look at your file in a browser and you should now see a red circle:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24602/image/circleadded.png"></figure><p>Read more about postcss-circle at: <a href="https://github.com/jedmao/postcss-circle">https://github.com/jedmao/postcss-circle</a><br></p><h3>Add a Triangle</h3><p>There are three types of triangle you can add using this plugin; isosceles, right-isosceles and equilateral. Each have slightly different sets of syntax, which you can read about in full at the plugin’s <a href="https://github.com/jedmao/postcss-triangle#introduction" rel="external" target="_blank">Github repo</a>.</p><p>We’ll go through adding an isosceles triangle, the syntax for which is:</p><pre class="brush: css noskimlinks noskimwords">triangle: pointing-&lt;up|down|left|right&gt;;
width: &lt;length&gt;;
height: &lt;length&gt;;
background-color: &lt;color&gt;;</pre><p>Let’s add this example isosceles triangle to our “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.isosceles-triangle {
triangle: pointing-right;
width: 7rem;
height: 8rem;
background-color: #c00;
}</pre><p>Compile the file and you should now see complete triangle CSS in your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.isosceles-triangle {
width: 0;
height: 0;
border-style: solid;
border-color: transparent;
border-width: 4rem 0 4rem 7rem;
border-left-color: #c00;
}</pre><p>To see the triangle in your “dest/index.html” file add this html:</p><pre class="brush: html noskimlinks noskimwords">&lt;div class="isosceles-triangle"&gt;&lt;/div&gt;</pre><p>On refreshing this file in your browser, you should now see a red isosceles triangle pointing to the right:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24602/image/triangleadded.png"></figure><p>Read more about postcss-triangle at: <a href="https://github.com/jedmao/postcss-triangle">https://github.com/jedmao/postcss-triangle</a></p><h2>Use Shortcuts for Common Tasks</h2><h3>Set Link Styling</h3><p>Setting colors for links is a job that has to be done in every project, and requires setting styles for default links as well as four different link states. The <a href="https://github.com/jedmao/postcss-all-link-colors">postcss-all-link-colors</a> plugin by Jed Mao lets you shortcut that process, outputting the colors for all your links at once.</p><p>Add the following to your “src/style.css”:</p><pre class="brush: css noskimlinks noskimwords">a {
@link-colors all #4D9ACC;
}</pre><p>Then compile your file and you’ll see all the required link states have been set:</p><pre class="brush: css noskimlinks noskimwords">a {
color: #4D9ACC;
}
a:visited {
color: #4D9ACC;
}
a:focus {
color: #4D9ACC;
}
a:hover {
color: #4D9ACC;
}
a:active {
color: #4D9ACC;
}</pre><p>You also have the option to generate a different color for a specific state. Just add some curly braces at the end of the rule, and inside that use the syntax <code class="inline">state: color;</code>.</p><p>Update the code you just added to your “src/style.css” file to the following:</p><pre class="brush: css noskimlinks noskimwords">a {
@link-colors all #4D9ACC {
hover: #5BB8F4;
}
}</pre><p>Now when you compile you’ll see the hover state has a different color to the rest of the styles:</p><pre class="brush: css noskimlinks noskimwords">a {
color: #4D9ACC
}
a:visited {
color: #4D9ACC;
}
a:focus {
color: #4D9ACC;
}
a:hover {
color: #5BB8F4;
}
a:active {
color: #4D9ACC;
}</pre><p>Read more about postcss-all-link-colors at: <a href="https://github.com/jedmao/postcss-all-link-colors">https://github.com/jedmao/postcss-all-link-colors</a><br></p><h3>Center Vertically or Horizontally</h3><p>Centering, either vertically or horizontally, is one of those tasks that’s a perpetual thorn in the side of CSS developers. Jed Mao’s <a href="https://github.com/jedmao/postcss-center">postcss-center</a> plugin makes the task a lot simpler with the introduction of <code class="inline">top: center;</code> for vertical centering, and <code class="inline">left: center;</code> for horizontal centering.</p><p>Add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.centered {
top: center;
left: center;
}</pre><p>Then compile it and you’ll see the following code:</p><pre class="brush: css noskimlinks noskimwords">.centered {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}</pre><p><strong>Note</strong>: the centering uses absolute positioning, so you will need to wrap your centered elements with a parent that uses relative, absolute or fixed positioning. Given absolutely positioned elements don’t affect the height or width of their parents, you’ll also want to set the height and width of the parent element to suit.</p><p>For example, add <code class="inline">left: center;</code> to the <code class="inline">.circle</code> class you created earlier so it will be horizontally centered:</p><pre class="brush: css noskimlinks noskimwords">.circle {
circle: 8rem #c00;
left: center;
}</pre><p>Then add this second class to act as a wrapper around the circle, giving it relative positioning and a height matching the circle:<br></p><pre class="brush: css noskimlinks noskimwords">.circle_wrap {
position: relative;
height: 8rem;
}</pre><p>Now add an element bearing this class as a wrapper around your existing circle html:<br></p><pre class="brush: html noskimlinks noskimwords">&lt;div class="circle_wrap"&gt;
&lt;div class="circle"&gt;&lt;/div&gt;
&lt;/div&gt;</pre><p>When you go back and refresh your page, you should see your circle has been horizontally centered:<br></p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24602/image/centeredcircle.png"></figure><p>Read more about postcss-center at: <a href="https://github.com/jedmao/postcss-center">https://github.com/jedmao/postcss-center</a><br></p><h3>Output Clearfix in One Line</h3><p>In any design that incorporates floats, creating a clearfix class is so handy that it’s just about essential. Sean King’s <a href="https://github.com/seaneking/postcss-clearfix">postcss-clearfix</a> plugin turns creating that clearfix styling into a one line job, by adding <code class="inline">fix</code> as a possible value that can be used with the <code class="inline">clear</code> property.</p><p>For a clearfix that will work on IE8+ add the following to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.clearfixed {
clear: fix;
}</pre><p>On compiling, you’ll see it has produced the following clearfix code, ready for use:</p><pre class="brush: css noskimlinks noskimwords">.clearfixed:after {
content: '';
display: table;
clear: both;
}</pre><p>If you need a clearfix that will work on IE6+ use the value <code class="inline">fix-legacy</code> instead of plain <code class="inline">fix</code>, like so:</p><pre class="brush: css noskimlinks noskimwords">.clearfixed_legacy {
clear: fix-legacy;
}</pre><p>When this code is compiled, you’ll see it includes a little extra content that makes it friendly to legacy browsers:</p><pre class="brush: css noskimlinks noskimwords">.clearfixed_legacy:before,
.clearfixed_legacy:after {
content: '';
display: table;
}
.clearfixed_legacy:after {
clear: both;
}
.clearfixed_legacy {
zoom: 1;
}</pre><p>Read more about postcss-clearfix at: <a href="https://github.com/seaneking/postcss-clearfix">https://github.com/seaneking/postcss-clearfix</a></p><h3>Set Positioning in One Line </h3><p>When you want to use non default positioning, i.e. <code class="inline">absolute</code>, <code class="inline">fixed</code> or <code class="inline">relative</code>, you have to type out the values for the element’s <code class="inline">top</code>, <code class="inline">right</code>, <code class="inline">bottom</code> and <code class="inline">left</code> positioning manually. There is no shorthand as you might use when setting margins or padding in one line. That is, until you install Sean King’s <a href="https://github.com/seaneking/postcss-position">postcss-position</a> plugin.</p><p>With this plugin, when using the <code class="inline">position</code> property, after setting a value of <code class="inline">absolute</code> / <code class="inline">fixed</code> / <code class="inline">relative</code>, you can declare <code class="inline">top</code>, <code class="inline">right</code>, <code class="inline">bottom</code> and <code class="inline">left</code> values in the same line. </p><p>Add the following example code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.absolute {
position: absolute 1rem 1rem 0 0;
}</pre><p>After compilation, you’ll see the shorthand has compiled into the separate lines you would normally have to type out manually.</p><pre class="brush: css noskimlinks noskimwords">.absolute {
position: absolute;
top: 1rem;
right: 1rem;
bottom: 0;
left: 0;
}</pre><p>The way these values are declared is with the same pattern as in <code class="inline">margin</code> or <code class="inline">padding</code> shorthand, i.e. you can also set top and bottom in the first value, then right and left in the second, or you can set one value to apply to all four.</p><p>For example, try out the following code:</p><pre class="brush: css noskimlinks noskimwords">.fixed_two_values {
position: fixed 2rem 1rem;
}
.relative_one_value {
position: relative 3rem;
}</pre><p>You should see it compile into:</p><pre class="brush: css noskimlinks noskimwords">.fixed_two_values {
position: fixed;
top: 2rem;
right: 1rem;
bottom: 2rem;
left: 1rem;
}
.relative_one_value {
position: relative;
top: 3rem;
right: 3rem;
bottom: 3rem;
left: 3rem;
}</pre><p>Read more about postcss-position at: <a href="https://github.com/seaneking/postcss-position">https://github.com/seaneking/postcss-position</a><br></p><h3>Set Width and Height at Once</h3><p>The <a href="https://github.com/postcss/postcss-size">postcss-size</a> plugin by Andrey Sitnik allows you to crunch the often used <code class="inline">width</code> and <code class="inline">height</code> properties down into a single <code class="inline">size</code> property. You can use it in two ways: passing two values with the first evaluating to width and the second to height, or passing one value that will be used for both width and height.</p><p>Test this out by adding the following CSS to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.size_a {
size: 1rem 2rem;
}
.size_b {
size: 1rem;
}</pre><p>On compilation, you should see this code now in your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.size_a {
width: 1rem;
height: 2rem;
}
.size_b {
width: 1rem;
height: 1rem;
}</pre><p>Read more about postcss-size at: <a href="https://github.com/postcss/postcss-size">https://github.com/postcss/postcss-size</a></p><h3>Set Vertical and Horizontal Spacing</h3><p>As a big lover of efficient coding, when writing out margins and padding, which are often equal on two sides, I’ve frequently found myself wishing there was a shortcut to declare vertical and horizontal spacing at once. I even wrote a few preprocessor mixins to do just that. But I won’t need those mixins anymore thanks to the <a href="https://github.com/davidhemphill/postcss-verthorz">postcss-verthorz</a> plugin by David Hemphill.</p><p>With this plugin you can use <code class="inline">padding-vert</code> or <code class="inline">margin-vert</code> to set vertical spacing, and <code class="inline">padding-horz</code> or <code class="inline">margin-horz</code> to set horizontal spacing. Add the following example code to your “src/style.css” file to see this working:</p><pre class="brush: css noskimlinks noskimwords">.spacing {
padding-vert: 1rem;
margin-horz: 2rem;
}</pre><p>After compilation you’ll see these rules have been expanded into full padding and margin declarations.</p><pre class="brush: css noskimlinks noskimwords">.spacing {
padding-top: 1rem;
padding-bottom: 1rem;
margin-left: 2rem;
margin-right: 2rem;
}</pre><p>You can also shortcut these properties even further by abbreviating them to two letters. The example code we used above could be abbreviated to the following and the output would be exactly the same:</p><pre class="brush: css noskimlinks noskimwords">.spacing_short {
pv: 1rem;
mh: 2rem;
}</pre><p>Read more about postcss-verthorz at: <a href="https://github.com/davidhemphill/postcss-verthorz">https://github.com/davidhemphill/postcss-verthorz</a></p><h3>Output Color Codes</h3><p>My favorite default text color is <code class="inline">#232323</code> and I don’t know if it’s just me, but I get tired of hammering out those same two digits over and over again. I often wished there was a shortcut, similar to the way you can trim <code class="inline">#ffffff</code> down to <code class="inline">#fff</code>. With the <a href="https://github.com/andrepolischuk/postcss-color-short">postcss-color-short</a> plugin by Andrey Polischuk, there is.</p><p>When using this plugin, if you set a two digit color code those digits will be repeated until a six digit code is created, e.g. <code class="inline">#23</code> will become <code class="inline">#232323</code>. If you set a one digit color code, it to will be repeated until there are three digits, e.g. <code class="inline">#f</code> will become <code class="inline">#fff</code>. You can even use it to set <code class="inline">rgba()</code> colors, where the first digit you pass will be repeated three times, and the second used as the alpha value, e.g. <code class="inline">rgba(0, 0.5)</code> will become <code class="inline">rgba(0, 0, 0, 0.5)</code>.</p><p>Add the following to your “src/style.css” file to try all the above out:</p><pre class="brush: css noskimlinks noskimwords">.short_colors {
color: #23;
background: #f;
border-color: rgba(0, 0.5);
}</pre><p>After compilation you’ll see all the colors have been output in their full form:</p><pre class="brush: css noskimlinks noskimwords">.short_colors {
color: #232323;
background: #fff;
border-color: rgba(0, 0, 0, 0.5);
}</pre><p>Read more about postcss-color-short at: <a href="https://github.com/andrepolischuk/postcss-color-short">https://github.com/andrepolischuk/postcss-color-short</a></p><h2>Summing Up</h2><p>Let’s quickly recap everything we’ve been over in this tutorial:</p><ul>
<li>Small every day coding tasks don’t seem like much individually, but they add up to a huge amount of time overall, so shortcutting them can be worthwhile</li>
<li>The <a href="https://github.com/seaneking/postcss-alias">postcss-alias</a> plugin lets you create your own shorthand for properties<br>
</li>
<li>The <a href="https://github.com/johnie/postcss-crip">postcss-crip</a> plugin has hundreds of predefined property shorthands</li>
<li>The <a href="https://github.com/jonathantneal/postcss-font-magician">postcss-font-magician</a> lets you use custom fonts as though they were default fonts, auto generating <code class="inline">@font-face</code> code for you</li>
<li>The <a href="https://github.com/jedmao/postcss-circle">postcss-circle</a> and <a href="https://github.com/jedmao/postcss-triangle">postcss-triangle</a> plugins make creating CSS circles and triangles straight forward and intuitive</li>
<li>The <a href="https://github.com/jedmao/postcss-all-link-colors">postcss-all-link-colors</a> plugin lets you output colors for all your link states at once<br>
</li>
<li>The <a href="https://github.com/jedmao/postcss-center">postcss-center</a> plugin provides vertical and horizontal centering with <code class="inline">top: center;</code> and <code class="inline">left: center;</code>
</li>
<li>The <a href="https://github.com/seaneking/postcss-clearfix">postcss-clearfix</a> plugin lets you output clearfix code with <code class="inline">clear: fix;</code>
</li>
<li>The <a href="https://github.com/seaneking/postcss-position">postcss-position</a> plugin allows you to add your <code class="inline">top</code>, <code class="inline">right</code>, <code class="inline">bottom</code> and <code class="inline">left</code> settings as part of your use of the <code class="inline">position</code> property</li>
<li>The <a href="https://github.com/postcss/postcss-size">postcss-size</a> plugin lets you set width and height at once<br>
</li>
<li>The <a href="https://github.com/davidhemphill/postcss-verthorz">postcss-verthorz</a> plugin allows horizontal spacing and vertical spacing to be output with single rules.</li>
<li>The <a href="https://github.com/andrepolischuk/postcss-color-short">postcss-color-short</a> plugin gives you the ability to use one and two digit hexcodes, and other color shortcuts.</li>
</ul><h2>In the Next Tutorial</h2><p>In the next tutorial we’ll move onto plugins that are great, but just don’t fall into any particular category. I’ll see you soon in “Miscellaneous Goodies”.</p>2015-11-02T13:47:13.000Z2015-11-02T13:47:13.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24592Using PostCSS with BEM and SUIT Methodologies<p>In this tutorial we’re going to learn how to use PostCSS to make development of BEM/SUIT style CSS easier and more efficient.</p><p>These two methodologies lay out a naming convention for classes that makes it easier to keep your styles tightly function-oriented, and helps other developers recognize the purpose of various classes just from the way they’re named.</p><p><a href="https://en.bem.info/method/" rel="external" target="_blank">BEM</a> was the forerunner of this type of class naming methodology, created by Yandex. The <a href="https://suitcss.github.io/" rel="external" target="_blank">SUIT</a> methodology is an approach based on BEM, but with some adjustments and additions made by Nicholas Gallagher. SUIT does everything BEM does, but to many users it is considered an enhancement.</p><p>Working with these methods definitely helps to produce better, more well structured CSS. However, the tricky part is that it can become tiresome manually typing out the class names required in this structure, and keeping track of how classes inter-relate can become a bit of a headache. </p><p>The <a href="https://github.com/ileri/postcss-bem" rel="external" target="_blank">postcss-bem</a> plugin by Malte-Maurice Dreyer alleviates these issues through a combination of shortcuts and nesting, which you will learn to use as we move through this tutorial.</p><p>But first, let’s have a quick primer on the BEM and SUIT methods, to make sure you have a clear picture of the benefits of using the postcss-bem plugin, and of the way it’s used.</p><h2>Quick Primer on BEM</h2><h3>Block</h3><p>In BEM <em>blocks</em> are high-level chunks of a design; the building blocks the site is made from. A block should be a piece of your site that’s independent of other pieces, and could theoretically be placed anywhere in your layout, even nested inside another block.<br></p><p>For example, search form “blocks” on your site might use the class <code class="inline">.search-form</code>.<br></p><h3>Element</h3><p>An <em>element</em> in BEM is a subsection inside a block. They are signified by appending a two underscore <code class="inline">__</code> separator and an element name to the parent block name.</p><p>For example, a search form might include heading, text field and submit button elements. Their class names might be <code class="inline">.search-form__heading</code>, <code class="inline">.search-form__text-field</code> and <code class="inline">.search-form__submit-button</code> respectively.</p><h3>Modifier</h3><p>A <em>modifier</em> is applied to a block or element to signify a change in its presentation, or a change in its state. They are signified by appending a separator and a modifier name to the block or element in question.</p><p>The <a href="https://en.bem.info/tools/bem/bem-naming/#custom-naming-convention" rel="external" target="_blank">official BEM site docs</a> state that modifier separators should be a single underscore <code class="inline">_</code>. However the <a href="https://en.bem.info/tools/bem/bem-naming/#convention-by-harry-roberts" rel="external" target="_blank">"BEM-like" convention of CSS Guidelines by Harry Roberts</a> employs two dashes <code class="inline">--</code> and is probably more widely used and known than the official BEM convention.</p><p>For example, in a design you may wish to present advanced search forms differently to regular search forms, and hence create the modifier class <code class="inline">.search-form_advanced</code> (official BEM) or <code class="inline">.search-form--advanced</code> (BEM-like).</p><p>In another example, you might want to change the form’s appearance due to a change in state, such as if invalid content has just been submitted, and hence create the modifier <code class="inline">.search-form_invalid</code> (official BEM) or <code class="inline">.search-form--invalid</code> (BEM-like).<br></p><h2>Quick Primer on SUIT</h2><p>SUIT comprises <em>Utilities</em> and <em>Components</em>. Within components there can be <em>Modifiers</em>, <em>Descendants</em> and <em>States</em>.<br></p><p>SUIT uses a combination of pascal case (PascalCase), camel case (camelCase) and dashes. Its conventions enforce a limit on the sometimes confusing number of dashes and underscores that can appear in BEM. For example, the BEM class <code class="inline">.search-form__text-field</code> would be <code class="inline">.SearchForm-textField</code> in SUIT.</p><h3>Utility</h3><p><em>Utilities</em> handle structure and positional styling, and are written in such a way that they can be applied anywhere in a component. They are prefixed with <code class="inline">u-</code> and written in camel case. For example, <code class="inline">.u-clearFix</code>.</p><h3>Component</h3><p>A <em>component</em> in SUIT takes the place of a <em>block</em> in BEM. Components are always written in pascal case and are only part of SUIT that uses pascal case, making them easy to identify. For example, <code class="inline">.SearchForm</code>.</p><h4>Component Namespace</h4><p>Components can optionally be prefixed with a namespace and single dash <code class="inline">nmsp-</code> to ensure conflicts are prevented, e.g. <code class="inline">.mine-SearchForm</code>.</p><h3>Descendent</h3><p>A <em>descendent</em> in SUIT replaces an <em>element</em> in BEM. It uses a single dash <code class="inline">-</code> and is written in camel case. For example <code class="inline">.SearchForm-heading</code>, <code class="inline">.SearchForm-textField</code> and <code class="inline">.SearchForm-submitButto</code>.</p><h3>Modifier</h3><p>SUIT uses <em>modifiers</em> as does BEM, however their role is more tightly controlled. A SUIT modifier is generally only applied directly to a component, not to a descendent. It should also not be used to represent state changes, as SUIT has a dedicated naming convention for states.</p><p>Modifiers are written in camel case and are preceded by two dashes <code class="inline">--</code>. For example, <code class="inline">.SearchForm--advanced</code>.</p><h3>State</h3><p><em>State</em> classes can be used to reflect changes to a component’s state. This allows them to be clearly differentiated from modifiers, which reflect modification of a component’s base appearance regardless of state. If necessary, a state can also be applied to a descendent.</p><p>States are prefixed with <code class="inline">is-</code> and are written in camel case. They are also always written as adjoining classes. For example <code class="inline">.SearchForm.is-invalid</code>.</p><h2>Setup Your Project</h2><p>Now that you have the essentials of BEM and SUIT down, it’s time to setup your project.</p><p>You’ll need an empty project using 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.</p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/using-postcss-with-bem-and-suit-methodologies/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.</p><h2>Install Plugins</h2><p>Next, you’ll need to install the postcss-bem plugin. We'll also be installing a plugin that can work in with it quite well: <a href="https://github.com/postcss/postcss-nested" rel="external" target="_blank">postcss-nested</a>.</p><p>Whether you’re using Gulp or Grunt, run the following command inside your project folder:</p><pre class="brush: bash noskimlinks noskimwords">npm install postcss-bem postcss-nested --save-dev</pre><p>Now we’re ready to load the plugins into your project.</p><h3>Load Plugins via Gulp</h3><p>If you’re using Gulp, add these variables under the variables already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var bem = require('postcss-bem');
var nested = require('postcss-nested');</pre><p>Now add each of those new variable names into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
bem,
nested
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load Plugins via Grunt</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('postcss-bem')(),
require('postcss-nested')()
]</pre><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><p>Okay, you’re ready to go. Let’s learn how to generate BEM and SUIT structure.</p><h2>BEM and SUIT with postcss-bem</h2><p>There can be some unwieldiness developing in BEM or SUIT structure when writing code out manually, as continually repeating the same identifiers in class names can become tiresome, and keeping track of which elements and descendents belong to which blocks and components can get confusing.</p><p>When you use postcss-bem however, it becomes easy to make sense of the structure of your code at a glance, and repetition in typing out class names becomes virtually non-existent.</p><h2>Generating SUIT Structure</h2><p>Despite its name, by default postcss-bem will output according to SUIT syntax rather than BEM. You can output in BEM syntax, which we will cover later, but the plugin is primarily designed to output SUIT, so for that reason, we’ll start with SUIT syntax.<br></p><h3>Generating a Component</h3><p>To create a component, use the syntax <code class="inline">@component ComponentName {...}</code>.</p><p>Try this out by adding a <code class="inline">SearchForm</code> component to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@component SearchForm {
padding: 0;
margin: 0;
}</pre><p>Compile it and your resulting code should be:</p><pre class="brush: css noskimlinks noskimwords">.SearchForm {
padding: 0;
margin: 0;
}</pre><h3>Generating a Descendent</h3><p>To create a descendent, use the syntax <code class="inline">@descendent descName {...}</code> nested inside the parent component.</p><p>Add a descendent named <code class="inline">textField</code> inside your <code class="inline">SearchForm</code> component like so:</p><pre class="brush: css noskimlinks noskimwords">@component SearchForm {
padding: 0;
margin: 0;
/* Nest descendent under component */
@descendent textField {
border: 1px solid #ccc;
}
}</pre><p>After compiling, you should now see:</p><pre class="brush: css noskimlinks noskimwords">.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm-textField {
border: 1px solid #ccc;
}</pre><h3>Generating a Modifier</h3><p>Create a modifier to a component with the syntax <code class="inline">@modifier name {...}</code>, nested inside the component it effects. Modifiers should typically be placed at the top of your component, above any descendents and states.</p><p>Add a modifier named <code class="inline">advanced</code> to your <code class="inline">SearchForm</code> component with the following code:</p><pre class="brush: css noskimlinks noskimwords">@component SearchForm {
padding: 0;
margin: 0;
/* Typically, place modifiers above descendents */
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
}
}</pre><p>Recompile your code and you should see your new <code class="inline">advanced</code> component modifier:</p><pre class="brush: css noskimlinks noskimwords">.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm--advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}</pre><h3>Generating a State</h3><p>States are created via the syntax <code class="inline">@when name {...}</code> and can be nested inside a component or a descendent.</p><p>Add a state named <code class="inline">invalid</code> to your <code class="inline">textField</code> descendent using this code:</p><pre class="brush: css noskimlinks noskimwords">@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
/* This creates a state for the textField descendant */
@when invalid {
border: 1px solid red;
}
}
}</pre><p>Now when you compile your code you’ll see it contains your new <code class="inline">invalid</code> state:</p><pre class="brush: css noskimlinks noskimwords">.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm--advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
.SearchForm-textField.is-invalid {
border: 1px solid red;
}</pre><h3>Namespacing Components</h3><p>You can namespace your components, and all the descendents, modifiers and states nested within them, by surrounding them with <code class="inline">@component-namespace name {...}</code>. You can, if you like, wrap your entire stylesheet with this namespace so all your classes are automatically prefixed with it.</p><p>Try this out by wrapping all your code so far with <code class="inline">@component-namespace mine {...}</code>:</p><pre class="brush: css noskimlinks noskimwords">@component-namespace mine {
@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
@when invalid {
border: 1px solid red;
}
}
}
}</pre><p>After compiling, you’ll see that now every one of your components is prefixed with <code class="inline">mine-</code>:</p><pre class="brush: css noskimlinks noskimwords">.mine-SearchForm {
padding: 0;
margin: 0;
}
.mine-SearchForm--advanced {
padding: 1rem;
}
.mine-SearchForm-textField {
border: 1px solid #ccc;
}
.mine-SearchForm-textField.is-invalid {
border: 1px solid red;
}</pre><h3>Generating a Utility</h3><p>Utilities are created with the syntax <code class="inline">@utility utilityName {...}</code>. You’ll recall that when setting up your project, you installed the postcss-nested plugin. We did this as it can be very handy to use in unison with postcss-bem, as you’ll see in this example where we create a <code class="inline">clearFix</code> utility:</p><pre class="brush: css noskimlinks noskimwords">@utility clearFix {
&amp;:before, &amp;:after {
content: "";
display: table;
}
&amp;:after {
clear: both;
}
/* If supporting IE 6/7 */
*zoom: 1;
}</pre><p>After adding the above code, compile and you’ll see this new utility has been created:</p><pre class="brush: css noskimlinks noskimwords">.u-clearFix {
/* If supporting IE 6/7 */
zoom: 1;
}
.u-clearFix:before, .u-clearFix:after {
content: "";
display: table;
}
.u-clearFix:after {
clear: both;
}</pre><h2>Generating BEM Structure</h2><p>To activate BEM syntax output in postcss-bem, pass the option <code class="inline">style: 'bem'</code> in your Gulpfile or Gruntfile like so:</p><pre class="brush: javascript noskimlinks noskimwords">/* Gulpfile */
var processors = [
bem({style: 'bem'}),
nested
];
/* Gruntfile */
processors: [
require('postcss-bem')({style: 'bem'}),
require('postcss-nested')()
]</pre><p>By default postcss-bem will use the official separator for a modifier of a single underscore <code class="inline">_</code>. If it’s important for your project that you use the more common separator of two dashes <code class="inline">--</code> instead, you can change the config for the postcss-bem plugin by going to the node_modules/postcss-bem folder of your project, opening up index.js, locating line 15 and changing this:</p><pre class="brush: javascript noskimlinks noskimwords"> bem: {
separators: {
namespace: '--',
descendent: '__',
modifier: '_'
}
}</pre><p>...to this:</p><pre class="brush: javascript noskimlinks noskimwords"> bem: {
separators: {
namespace: '_',
descendent: '__',
modifier: '--'
}
}</pre><h3>Generating a Block</h3><p>Because a “block” in BEM correlates with a “component” in SUIT, use the syntax <code class="inline">@component block-name {...}</code> to generate a block.</p><p>To create a <code class="inline">search-form</code> block add this code:</p><pre class="brush: css noskimlinks noskimwords">@component search-form {
padding: 0;
margin: 0;
}</pre><p>Then compile and you should see:</p><pre class="brush: css noskimlinks noskimwords">.search-form {
padding: 0;
margin: 0;
}</pre><h3>Generating a Element</h3><p>As an “element” in BEM correlates to a “descendent” in SUIT, they can be created with the syntax <code class="inline">@descendent element-name {...}</code> nested inside the parent block.</p><p>To create a <code class="inline">text-field</code> element add the following:</p><pre class="brush: css noskimlinks noskimwords">@component search-form {
padding: 0;
margin: 0;
@descendent text-field {
border: 1px solid #ccc;
}
}</pre><p>On compilation, you’ll see your new element has been created:</p><pre class="brush: css noskimlinks noskimwords">.search-form {
padding: 0;
margin: 0;
}
.search-form__text-field {
border: 1px solid #ccc;
}</pre><h3>Generating a Modifier</h3><p>Even though BEM allows modifiers to both blocks and elements, the postcss-bem plugin will only process them if nested inside blocks and not elements, due to the SUIT convention of modifiers being applied to components not descendents. They can be created with the syntax <code class="inline">@modifier name {...}</code>, nested inside its parent block.</p><p>Add an <code class="inline">advanced</code> modifier to your <code class="inline">search-form</code> component like so:</p><pre class="brush: css noskimlinks noskimwords">@component search-form {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent text-field {
border: 1px solid #ccc;
}
}</pre><p>And on compilation it will yield:</p><pre class="brush: css noskimlinks noskimwords">.search-form {
padding: 0;
margin: 0;
}
.search-form_advanced {
padding: 1rem;
}
.search-form__text-field {
border: 1px solid #ccc;
}</pre><h3>No Utilities or States, but Namespaces Are In</h3><p>While in BEM mode the <code class="inline">@utility</code> and <code class="inline">@when</code> syntaxes will not compile into anything, given BEM does not use utilities or states.</p><p>However, even though it’s not generally part of BEM, the <code class="inline">@component-namespace</code> syntax will still work if you wish to use it in your BEM stylesheet. It will prefix your classes with <code class="inline">name--</code>:</p><pre class="brush: css noskimlinks noskimwords">.mine--search-form {
padding: 0;
margin: 0;
}
.mine--search-form_advanced {
padding: 1rem;
}
.mine--search-form__text-field {
border: 1px solid #ccc;
}</pre><h2>Let’s Recap</h2><p>Now you know all about how to shortcut your BEM and SUIT development, and make the overall process more easier. Let’s summarize everything we’ve covered:</p><ul>
<li>BEM and SUIT are class naming conventions that help to keep stylesheets function oriented and organized, as well as helping other developers recognize the purpose of various classes.</li>
<li>SUIT is like BEM, but with some extras added and adjustments made</li>
<li>The postcss-bem plugin provides shortcuts for creating BEM and SUIT classes, such as <code class="inline">@component</code>, <code class="inline">@descendent</code>, <code class="inline">@modifier</code> etc.</li>
<li>The plugin also allows code to be nested in a helpful way, e.g. modifiers are nested inside the component or block they modify.</li>
<li>Namespacing can be done automatically by wrapping classes with <code class="inline">@component-namespace name {...}</code>
</li>
</ul><h2>In the Next Tutorial</h2><p>Coming up next we look at another great way to take advantage of PostCSS, and that is by putting together a toolkit of shorthand and shortcuts we can take to make our coding faster and more efficient.</p><p>I’ll see you there!</p>2015-10-30T10:35:27.000Z2015-10-30T10:35:27.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24591Using PostCSS Together with Sass, Stylus, or LESS<p>If you’re interested in using PostCSS, but you still love your favorite preprocessor, don’t worry. You needn’t make a choice between the two–you can use them right alongside one another.</p><p>There are several PostCSS plugins that compliment preprocessors very well, as they add functionality into your workflow that would otherwise be impossible, or at least more difficult, using only a preprocessor.</p><p>We’ll touch on some of these complimentary plugins, then we’ll go through setup guides to show you how to use PostCSS side by side with Sass, Stylus or LESS.</p><h2>Why Use Both?</h2><p>Before we get into <em>how</em> you can use preprocessors together with PostCSS, we’ll talk a little bit about <em>why</em> you would want to. The short answer is: to gain access to PostCSS plugins whose functionality compliments preprocessors. To show you why these are worth having, we’ll go over a handful of plugins that work really well with preprocessors.</p><p><strong>Note</strong>: it may be possible to achieve similar end results by using mixins and functions in regular preprocessor code, but with each of the examples below the process is handled automatically. You write your CSS normally and the plugins take care of everything for you, with no functions to call, no mixins to include, or arguments to pass.</p><h3>autoprefixer</h3><p>There have been many a preprocessor mixin written to handle the insertion of vendor prefixes. For example, you might have used <code class="inline">@include box-sizing(border-box);</code> from the Compass library to output vendor prefixed <code class="inline">box-sizing</code> rules.</p><p>The trouble with relying on mixins for vendor prefixes is:</p><ol>
<li>You first have to know a property needs prefixes before you can decide to deploy a mixin for it.</li>
<li>You have to know the name of the associated mixin and how to use it.</li>
<li>You have to keep tabs on when vendor prefixes are no longer required for each property (I know I was prefixing <code class="inline">box-sizing</code> for way to long...)</li>
</ol><p>Autoprefixer eliminates these concerns by handling the process of vendor prefixing automatically. Autoprefixer scans your CSS, checks it against data from CanIUse.com, then adds the prefixes that are required.</p><p>Read more about Autoprefixer at: <a href="https://github.com/postcss/autoprefixer">https://github.com/postcss/autoprefixer</a><br></p><h3>rtlcss</h3><p>Generating both default and RTL (right to left) stylesheets from a single source is also something that has been done with preprocessors, however it typically requires using several mixins and/or interpolating variables into your code in several places. For example, rather than writing <code class="inline">margin-left: 1rem;</code> you might need to write <code class="inline">margin-#{dir}: 1rem;</code> or <code class="inline">@include margin-left( 1rem );</code>.</p><p>With the <a href="https://github.com/MohammadYounes/rtlcss">rtlcss</a> plugin by Mohammad Younes however, you don’t need to use mixins or variable interpolation, you just write your stylesheet as you normally would and the plugin will find all instances or “right” or “left” and swap them around. So <code class="inline">margin-left: 1rem;</code> automatically becomes <code class="inline">margin-right: 1rem;</code> without you having to write any special code to make it happen.</p><p>Read more about rtlcss at: <a href="https://github.com/MohammadYounes/rtlcss">https://github.com/MohammadYounes/rtlcss</a></p><h3>postcss-colorblind</h3><p>With the <a href="https://github.com/btholt/postcss-colorblind">postcss-colorblind</a> plugin by Brian Holt you can automatically generate different versions of your stylesheet that give you first-hand experience of what your design would look like to a person with color blindness. It can simulate eight different types of colorblindness, helping you get a really solid grasp on just how accessible your color schemes are.</p><p>This is an example of functionality that you really do have to go to PostCSS to find, as it would be very difficult for preprocessors to achieve.</p><p>Read more about postcss-colorblind at: <a href="https://github.com/btholt/postcss-colorblind">https://github.com/btholt/postcss-colorblind</a><br></p><h3>postcss-svgo</h3><p>The <a href="https://github.com/ben-eb/postcss-svgo">postcss-svgo</a> plugin by Ben Briggs can give you hands free optimization of inline SVG code. For example this:</p><pre class="brush: css noskimlinks noskimwords">background: url('data:image/svg+xml;utf-8,&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"&gt;&lt;svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"&gt;&lt;circle cx="50" cy="50" r="40" fill="yellow" /&gt;&lt;/svg&gt;');</pre><p>Can be boiled down to this, less than half the code:</p><pre class="brush: css noskimlinks noskimwords">background: url('data:image/svg+xml;utf-8,&lt;svg xmlns="http://www.w3.org/2000/svg"&gt;&lt;circle cx="50" cy="50" r="40" fill="#ff0"/&gt;&lt;/svg&gt;');</pre><p>Read more about postcss-svgo at: <a href="https://github.com/ben-eb/postcss-svgo">https://github.com/ben-eb/postcss-svgo</a><br></p><h3>cssnano</h3><p>While preprocessors can strip whitespace and comments, the cssnano pack by Ben Briggs can perform all kinds of optimizations above and beyond these two steps. We cover cssnano in detail in the tutorial <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568" target="_self">For Minification and Optimization</a>.</p><p>Read more about cssnano at: <a href="https://github.com/ben-eb/cssnano">https://github.com/ben-eb/cssnano</a></p><h3>postcss-font-magician</h3><p>The <a href="https://github.com/jonathantneal/postcss-font-magician">postcss-font-magician</a> plugin by Jonathan Neal makes adding custom fonts as easy as using regular fonts. You don’t need to use any mixins, just add a <code class="inline">font-family</code> rule as you normally would:</p><pre class="brush: css noskimlinks noskimwords">body {
font-family: "Alice";
}</pre><p>...and the plugin will handle full <code class="inline">@font-face</code> generation for you:</p><pre class="brush: css noskimlinks noskimwords">@font-face {
font-family: "Alice";
font-style: normal;
font-weight: 400;
src: local("Alice"), local("Alice-Regular"),
url("http://fonts.gstatic.com/s/alice/v7/sZyKh5NKrCk1xkCk_F1S8A.eot?#") format("eot"),
url("http://fonts.gstatic.com/s/alice/v7/l5RFQT5MQiajQkFxjDLySg.woff2") format("woff2"),
url("http://fonts.gstatic.com/s/alice/v7/_H4kMcdhHr0B8RDaQcqpTA.woff") format("woff"),
url("http://fonts.gstatic.com/s/alice/v7/acf9XsUhgp1k2j79ATk2cw.ttf") format("truetype")
}
body {
font-family: "Alice";
}</pre><p>Read more about postcss-font-magician at: <a href="https://github.com/jonathantneal/postcss-font-magician">https://github.com/jonathantneal/postcss-font-magician</a></p><h2>Project Setup</h2><p>There are six setup guides below: a Gulp and Grunt guide for each major preprocessor. There’s no need to read all six, you can just skip straight to the guide for your preferred preprocessor and build tool. If you’re not sure whether to use Gulp or Grunt, Gulp is definitely the simpler choice for this tutorial.</p><p>For whichever guide you follow, you’ll need to begin with an empty Gulp or Grunt project. You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don’t want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/using-postcss-together-with-sass-stylus-or-less" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.<br></p><h3>Install PostCSS Plugins Into Your Project</h3><p>After you setup an empty project for one of the sections below, you’ll also need to install two PostCSS plugins: Autoprefixer and cssnano. You can do so by running the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install autoprefixer cssnano --save-dev</pre><p>We’ll be using these two plugins to test that PostCSS and your preprocessor are working together as expected.</p><h2>Preprocess Before PostCSS</h2><p>The first rule of using a preprocessor with PostCSS is that you should always run said preprocessor <em>first</em>. This is because you don’t want to have any preprocessor-specific syntax in your code that might choke a PostCSS plugin, and you also don’t want PostCSS making changes to your code that might prevent a preprocessor from running as expected.</p><h2>PostCSS Plugins and “PostCSS Test Code”</h2><p>For each of the preprocessors we setup, we‘ll have them run autoprefixer and cssnano after the preprocessor has finished its compilation. In each case, we’ll need to add some test code for these two plugins to operate on. </p><p>To save repeating the same code in each section below, when you see an instruction telling you to add your PostCSS test code, please add this to the preprocessor source file you’re working on:</p><pre class="brush: css noskimlinks noskimwords">.css_nano, .css_nano + p, [class*="css_nano"], .css_nano {
/* cssnano will remove this comment */
display: flex;
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));
}</pre><p>If successful, your compiled code will in each case come out as:</p><pre class="brush: css noskimlinks noskimwords">.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><p><strong>Note</strong>: the uses of flexbox have been autoprefixed, and cssnano has performed multiple optimizations of the code. We’re using the same code to test cssnano as we did in the previous <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568" target="_self">For Minification and Optimization</a> tutorial, so please refer to the “cssnano” section therein for details on the optimizations being performed.</p><h2>
<span class="sectionnum">1.</span> Sass + PostCSS</h2><p>Because you’re already working with Node.js to run Gulp or Grunt and PostCSS, the easiest way to use Sass alongside them is to do it via LibSass. This is also considerably faster than Ruby Sass. We’ll be deploying LibSass via the <a href="https://www.npmjs.com/package/gulp-sass" rel="external" target="_blank">gulp-sass</a> or <a href="https://github.com/gruntjs/grunt-contrib-sass" rel="external" target="_blank">grunt-contrib-sass</a> modules.</p><h3>Setup via Gulp</h3><p>Install the gulp-sass module into your project with <code class="inline">npm install gulp-sass --save-dev</code>. </p><p>Now you can update your Gulpfile to the following:</p><pre class="brush: javascript noskimlinks noskimwords">var gulp = require('gulp');
var postcss = require('gulp-postcss');
var sass = require('gulp-sass');
var autoprefixer = require('autoprefixer');
var cssnano = require('cssnano');
gulp.task('css', function () {
var processors = [
autoprefixer,
cssnano
];
return gulp.src('./src/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(postcss(processors))
.pipe(gulp.dest('./dest'));
});</pre><p>Let’s break down what we’ve changed from the default starter Gulpfile:</p><ul>
<li>Added variables to load <code class="inline">gulp-sass</code>, <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code>
</li>
<li>Added the <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code> variables to the <code class="inline">processors</code> array</li>
<li>Edited the file extension on the source file we’re compiling to “.scss” instead of “.css”</li>
<li>Added a new <code class="inline">pipe()</code> line, <code class="inline">.pipe(sass()...</code>, to process the Sass, being sure to place it before the line that processes PostCSS</li>
</ul><p>Now we can run some tests to make sure both Sass and PostCSS are compiling as expected.</p><h4>Test Preprocessor</h4><p>Rename your existing “src/style.css” file to “src/style.scss” and add the following test code to it:</p><pre class="brush: css noskimlinks noskimwords">$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}</pre><p>Run <code class="inline">gulp css</code> and you should see a new “style.css” file appear in your “dest” folder with the contents:</p><pre class="brush: css noskimlinks noskimwords">body {
font: 100% Helvetica, sans-serif;
color: #333; }
</pre><h4>Test PostCSS</h4><p>Now, add the PostCSS test code provided earlier in this tutorial to your “style.scss” file. </p><p>Run your <code class="inline">gulp css</code> command and you should see the correct code appear in your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><h3>Setup via Grunt</h3><p>Into your new Grunt project, install the grunt-contrib-sass module with <code class="inline">npm install grunt-contrib-sass</code>. </p><p>Then add a <code class="inline">grunt.loadNpmTasks()</code> function for it under the existing one you have for PostCSS:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-sass');</pre><p>You’ll now need to setup a new task for processing Sass. After this line:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.initConfig({</pre><p>...but before the existing <code class="inline">postcss</code> task, add this code:</p><pre class="brush: javascript noskimlinks noskimwords"> sass: {
dist: {
files: {
'src/style.css': 'src/style.scss'
}
}
},</pre><p>Now we’ll register a task that will run Sass and then PostCSS. After the <code class="inline">grunt.loadNpmTasks()</code> function you just inserted, add:</p><pre class="brush: javascript noskimlinks noskimwords">grunt.registerTask('css', ['sass', 'postcss']);</pre><h4>Test Preprocessor</h4><p>To test your setup, rename your existing “src/style.css” file to “style.scss”. Add this Sass code to it:</p><pre class="brush: css noskimlinks noskimwords">$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}</pre><p>Run the command <code class="inline">grunt css</code> and you should see a new file created in your “dest” folder named “style.css” and containing this code:</p><pre class="brush: css noskimlinks noskimwords">body {
font: 100% Helvetica, sans-serif;
color: #333; }</pre><h4>Setup PostCSS</h4><p>We’ll now get our Autoprefixer and cssnano plugins running. Update your Gruntfile’s <code class="inline">processors</code> array to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('autoprefixer')(),
require('cssnano')()
]</pre><h4>Test PostCSS</h4><p>Add the PostCSS test code to your “style.scss” file, run the command <code class="inline">grunt css</code> again and you should find your recompiled “dest/style.css” file now contains the correct autoprefixed and optimized code.</p><h2>
<span class="sectionnum">2.</span> Stylus + PostCSS</h2><p>Stylus and PostCSS work particularly well together thanks to the creation of the <a href="https://github.com/seaneking/poststylus" rel="external" target="_blank">PostStylus</a> package by Sean King, which combines the processing of both Stylus and PostCSS. If you’re a Stylus developer, you can just add PostStylus to your compilation process and immediately have access to using PostCSS plugins as part of your workflow.</p><p>PostStylus: <a href="https://github.com/seaneking/poststylus">https://github.com/seaneking/poststylus</a><br></p><h3>Setup via Gulp</h3><p>If you’re using the premade Gulpfile from the starter project, you’ll note is uses the gulp-postcss plugin. This is actually only there as it’s needed for the Sass and LESS setup processes, but for Stylus we won’t need it because we’re using PostStylus as our compiler instead. </p><p>You can remove it from your project with <code class="inline">npm uninstall gulp-postcss --save-dev</code>, and delete this line from your Gulpfile:</p><pre class="brush: javascript noskimlinks noskimwords">var postcss = require('gulp-postcss');</pre><p>Now we can install the two plugins we need for Stylus and PostCSS compilation, by running the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install gulp-stylus poststylus --save-dev</pre><p>Update your Gulpfile to become:</p><pre class="brush: javascript noskimlinks noskimwords">var gulp = require('gulp');
var stylus = require('gulp-stylus');
var poststylus = require('poststylus');
var autoprefixer = require('autoprefixer');
var cssnano = require('cssnano');
gulp.task('css', function () {
var processors = [
autoprefixer,
cssnano
];
return gulp.src('./src/*.styl')
.pipe(stylus({
use: [
poststylus(processors)
]
}))
.pipe(gulp.dest('./dest'));
});</pre><p>Here’s what we’ve done above:</p><ul>
<li>Added variables to load <code class="inline">gulp-stylus</code>, <code class="inline">poststylus</code>, <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code>
</li>
<li>Added the <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code> variables to the <code class="inline">processors</code> array</li>
<li>Edited the file extension on the source file we’re compiling to “.styl” instead of “.css”</li>
<li>Removed the <code class="inline">.pipe()</code> line that read <code class="inline">.pipe(postcss(processors))</code> </li>
<li>Replaced it with <code class="inline">.pipe(stylus({...</code>, to set the gulp-stylus and poststylus modules to handle our compilation </li>
</ul><h4>Test Preprocessor</h4><p>Now we’re ready to test compilation. In your “src” folder, rename “style.css” to “style.styl” and add this test Stylus code:</p><pre class="brush: css noskimlinks noskimwords">$font-stack = Helvetica, sans-serif
$primary-color = #333
body
font: 100% $font-stack
color: $primary-color</pre><p>Run the <code class="inline">gulp css</code> command and you should see a “style.css” file appear in your “dest” folder with this content:</p><pre class="brush: css noskimlinks noskimwords">body {
font: 100% Helvetica, sans-serif;
color: #333;
}</pre><h4>Test PostCSS</h4><p>Add the PostCSS test code provided earlier to your “style.styl” file, ensuring only tab indents are in the pasted code, not spaces.</p><p>Recompile, and check that you have the appropriate output in your “dest/style.css” file.<br></p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><h3>Setup via Grunt<br>
</h3><p>As with the Gulp project for Stylus, the default PostCSS compiler that comes with the starter project is not required, being there purely for Sass and LESS setup processes. You can remove it from your project with <code class="inline">npm uninstall grunt-postcss --save-dev</code>.</p><p>Now we can install grunt-contrib-stylus and poststylus with the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install grunt-contrib-stylus poststylus --save-dev</pre><p>We’re no longer going to be using grunt-postcss, so locate this line:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.loadNpmTasks('grunt-postcss');</pre><p>And replace it with:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.loadNpmTasks('grunt-contrib-stylus');</pre><p>Given we’re not using grunt-postcss, that means we’ll no longer need the <code class="inline">postcss</code> task we have defined inside <code class="inline">grunt.initConfig({...});</code>. Delete that task config and replace it with this new <code class="inline">stylus</code> task:</p><pre class="brush: javascript noskimlinks noskimwords"> stylus: {
compile: {
options: {
},
files: {
'dest/style.css': 'src/style.styl'
}
}
}</pre><h4>Test Preprocessor</h4><p>Now we’re ready to test compilation. In your “src” folder, rename “style.css” to “style.styl” and add this test Stylus code:</p><pre class="brush: css noskimlinks noskimwords">$font-stack = Helvetica, sans-serif
$primary-color = #333
body
font: 100% $font-stack
color: $primary-color</pre><p>Run the command <code class="inline">grunt stylus</code> and you should see a “style.css” file appear in your “dest” folder with this content:</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}</pre><h4>Setup PostCSS</h4><p>To add our PostCSS plugins into the compilation process, we first need to add this code to the very top of our Gruntfile, above the <code class="inline">module.exports...</code> line:</p><pre class="brush: javascript noskimlinks noskimwords">var poststylus = function() {
return require('poststylus')(['autoprefixer', 'cssnano'])
};</pre><p>This is where you’ll load in any PostCSS plugins you want to use, rather than in a <code class="inline">processors</code> array as you’ll be used to from our other tutorials.</p><p>Then find the <code class="inline">options</code> object inside the stylus task, and update it to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> options: {
use: [poststylus]
},</pre><p>This tells grunt-contrib-stylus to use poststylus during compilation, and its plugins along with it.</p><h4>Test PostCSS</h4><p>Add the “PostCSS test code” to your “src/style.styl” file, run <code class="inline">grunt stylus</code>, and you should see the following content written into your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><h2>
<span class="sectionnum">3.</span> LESS + PostCSS</h2><h3>Setup via Gulp</h3><p>Install the gulp-less module into your project with <code class="inline">npm install gulp-less --save-dev</code>. </p><p>Now you can update your Gulpfile to the following:</p><pre class="brush: javascript noskimlinks noskimwords">var gulp = require('gulp');
var postcss = require('gulp-postcss');
var less = require('gulp-less');
var autoprefixer = require('autoprefixer');
var cssnano = require('cssnano');
gulp.task('css', function () {
var processors = [
autoprefixer,
cssnano
];
return gulp.src('./src/*.less')
.pipe(less())
.pipe(postcss(processors))
.pipe(gulp.dest('./dest'));
});</pre><p>Let’s break down what we’ve changed from the default starter Gulpfile:</p><ul>
<li>Added variables to load <code class="inline">gulp-less</code>, <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code>
</li>
<li>Added the <code class="inline">autoprefixer</code> and <code class="inline">cssnano</code> variables to the <code class="inline">processors</code> array</li>
<li>Edited the file extension on the source file we’re compiling to “.less” instead of “.css”</li>
<li>Added <code class="inline">.pipe(less())</code> to process the LESS, being sure to place it before the line that processes PostCSS</li>
</ul><h4>Test Preprocessor</h4><p>Now we can run some tests to make sure both LESS and PostCSS are compiling as expected.</p><p>Rename the existing “src/style.css” file to “src/style.less” and add the following test code to it:</p><pre class="brush: css noskimlinks noskimwords">@font-stack: Helvetica, sans-serif;
@primary-color: #333;
body {
font: 100% @font-stack;
color: @primary-color;
}</pre><p>Run <code class="inline">gulp css</code> and you should see a new “style.css” file appear in your “dest” folder with the contents:</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}</pre><h4>Test PostCSS</h4><p>Now, to your “style.less” file add the PostCSS test code provided earlier in this tutorial. </p><p>Run your <code class="inline">gulp css</code> command and you should see the correct code now appearing in your “dest/style.css” file.</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><h3>Setup via Grunt</h3><p>Into your new Grunt project, install the grunt-contrib-less module with <code class="inline">npm install grunt-contrib-less</code>, then add a <code class="inline">grunt.loadNpmTasks()</code> function for it under the existing one you have for PostCSS:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-less');</pre><p>You’ll now need to setup a new task for processing LESS. After this line:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.initConfig({</pre><p>...but before the existing <code class="inline">postcss</code> task, add this code:</p><pre class="brush: javascript noskimlinks noskimwords"> less: {
production: {
files: {
'src/style.css': 'src/style.less'
}
}
},</pre><p>Now we’ll register a task, to run LESS and then PostCSS. After the <code class="inline">grunt.loadNpmTasks()</code> function you just inserted, add:</p><pre class="brush: javascript noskimlinks noskimwords"> grunt.registerTask('css', ['less', 'postcss']);</pre><h4>Test Preprocessor</h4><p>To test your setup, rename your “src/style.css” file “style.less”. Add this LESS code to it:</p><pre class="brush: css noskimlinks noskimwords">@font-stack: Helvetica, sans-serif;
@primary-color: #333;
body {
font: 100% @font-stack;
color: @primary-color;
}</pre><p>Run the command <code class="inline">grunt css</code> and you should see a new file created in your “dest” folder named “style.css” and containing this code:</p><pre class="brush: css noskimlinks noskimwords">body {
font: 100% Helvetica, sans-serif;
color: #333333;
}</pre><h4>Setup PostCSS</h4><p>Now we’ll add our PostCSS plugins into compilation flow. Update your Gruntfile’s <code class="inline">processors</code> array to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('autoprefixer')(),
require('cssnano')()
]</pre><h4>Test PostCSS</h4><p>Add the PostCSS test code to your “style.less” file, run the command <code class="inline">grunt css</code> again and you should find your recompiled “dest/style.css” file now contains the correct autoprefixed and optimized code:</p><pre class="brush: css noskimlinks noskimwords">body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}</pre><h2>In the Next Tutorial</h2><p>Next up we’re going to check out something you could almost consider a different type of preprocessing–using PostCSS to automatically generated BEM/SUIT compliant CSS classes. This process makes BEM/SUIT development much easier to keep track of, not to mention more efficient.</p><p>See you in the next tutorial!</p>2015-10-27T10:07:58.000Z2015-10-27T10:07:58.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24584PostCSS Deep Dive: Roll Your Own Preprocessor<p>In <a href="http://webdesign.tutsplus.com/tutorials/postcss-deep-dive-preprocessing-with-precss--cms-24583" target="_self">the previous tutorial</a> we went through how to use the excellent preprocessing pack “PreCSS”. In this tutorial we’ll be approaching PostCSS-based preprocessing in a different way; installing a hand-picked selection of plugins to custom build our preprocessor from the ground up.</p><p>I'm going to take you through the setup of what I <em>personally</em> find to be a great mix of language extension plugins. But when it comes to you rolling your own preprocessor you might choose to use only some of the plugins we cover here, or you might choose none at all, instead going with other options.</p><p>That’s the beauty of this process; you can have your preprocessor setup however you choose. The purpose of this tutorial will be to give you hands on experience of putting together a PostCSS preprocessor, and to fill you in on the features of the currently available plugins so you can decide for yourself which you want to use.</p><p>Let's begin!</p><h2>Setup Your Project</h2><p>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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/postcss-deep-dive-roll-your-own-preprocessor/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, and extract either the provided Gulp or Grunt starter project into an empty project folder. <br></p><p>Then, with a terminal or command prompt pointed at the folder, run the command <code class="inline">npm install</code>.</p><h2>Note on Plugin Installation</h2><p>This tutorial will assume you‘ve followed the previous entries in the series and are now familiar with how to install a plugin into your project and load it via your Gulpfile or Gruntfile.</p><p><strong>Important! </strong>As we go through, be sure to load the plugins into your Gulpfile/Gruntfile in the order you see in this tutorial; load order is important in PostCSS to keep everything running smoothly.</p><h2>Add Imports for Partials</h2><p>The very first place we’re going to start with putting together our custom preprocessor is imports. You have already seen PostCSS inlining of <code class="inline">@import</code> stylesheets in the previous tutorials <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568" target="_self">For Minification and Optimization</a> and <a href="http://webdesign.tutsplus.com/tutorials/postcss-deep-dive-preprocessing-with-precss--cms-24583" target="_self">Preprocessing with PreCSS</a>. The way imports will be used in this preprocessor is no different.</p><p>We just touched above on the fact that load order is important in PostCSS, and here we find the first example of this. We want to ensure all <code class="inline">@import</code> files are inlined as the very first step, so that we have all the code of our project in one place for the rest of our plugins to run against. </p><p>For example, we might store all our variables in a partial file, and use <code class="inline">@import</code> to bring that partial into our main stylesheet. If we didn’t run the plugin that inlines <code class="inline">@import</code> files first, our variables wouldn’t be imported and hence wouldn’t available for the rest of our processing to work with.</p><h3>First, Change Gulpfile Source File to “style.css”</h3><p>Because we’re going to start importing partials, we want to make a little tweak to our Gulpfile before we add our import functionality. </p><p><strong>Note</strong>: if using Grunt, you won’t need to make any changes at this stage.</p><p>Right now we’re having any “.css” file found in the “src” folder compiled, but we don’t want to accidentally compile partial files. We’ll be importing everything into our “style.css” file so it’s the only one that needs to be compiled.</p><p>Find this line:</p><pre class="brush: javascript noskimlinks noskimwords"> return gulp.src('./src/*.css')</pre><p>...and change it to:</p><pre class="brush: javascript noskimlinks noskimwords"> return gulp.src('./src/style.css')</pre><h3><strong>Import Plugin Used:</strong></h3><ul><li>postcss-import by Maxime Thirouin: <a href="https://github.com/postcss/postcss-import">https://github.com/postcss/postcss-import</a>
</li></ul><p>This is the same plugin we used in the “For Minification and Optimization” tutorial, and that is also used in PreCSS, so you’ll be somewhat familiar with it at this point.</p><p>Install the plugin into your project, then in your “src” folder create a file named “_vars.css” and add some basic test code to it. Note we haven’t added variables functionality yet, so just some straight CSS, for example:</p><pre class="brush: css noskimlinks noskimwords">.test {
background: black;
}</pre><p>Now import your new variables file into your main “src/style.css” file by adding this code at the first line:</p><pre class="brush: css noskimlinks noskimwords">@import "_vars";</pre><p>Compile your code, then check your “dest/style.css” file and you should see it now contains the code from your “_vars.css” file.</p><h2>Add Mixins</h2><h3><strong>Mixins Plugin Used:</strong></h3><ul><li>postcss-mixins by Andrey Sitnik: <a href="https://github.com/postcss/postcss-mixins">https://github.com/postcss/postcss-mixins</a>
</li></ul><p><strong>Note</strong>: this plugin <em>must</em> be executed before the <a href="https://github.com/postcss/postcss-nested" rel="external" target="_blank">postcss-nested</a> and <a href="https://github.com/postcss/postcss-simple-vars" rel="external" target="_blank">postcss-simple-vars</a> plugins, both of which we’ll be using. </p><p>Go ahead and install postcss-mixins, then add the following code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@define-mixin icon $network, $color {
.button.$(network) {
background-image: url('img/$(network).png');
background-color: $color;
}
}
@mixin icon twitter, blue;</pre><p>After compilation your “dest/style.css” should have the following compiled code added to it:</p><pre class="brush: css noskimlinks noskimwords">.button.twitter {
background-image: url('img/twitter.png');
background-color: blue;
}</pre><p>The <a href="https://github.com/postcss/postcss-mixins">postcss-mixins</a> plugin we’re using here is the same one as used in PreCSS. We went over how to use it in the tutorial on PreCSS, so for full details on its syntax check out the “Mixins” section of the previous tutorial.</p><h3><strong>Other Mixin Plugin Options:</strong></h3><ul><li>postcss-sassy-mixins by Andy Jansson: <a href="https://github.com/andyjansson/postcss-sassy-mixins">https://github.com/andyjansson/postcss-sassy-mixins</a>
</li></ul><p>If you’d prefer to use Sass syntax when creating mixins, check out Andy Jansson's <a href="https://github.com/andyjansson/postcss-sassy-mixins">postcss-sassy-mixins</a> plugin, which works in the same way as <a href="https://github.com/postcss/postcss-mixins">postcss-mixins</a> but with the syntax <code class="inline">@mixin</code> to define a mixin, and <code class="inline">@include</code> to use one.<br></p><h2>Add “for” Loops</h2><h3><strong>“for” Loops Plugin Used:</strong></h3><ul><li>postcss-for by Anton Yakushev: <a href="https://github.com/antyakushev/postcss-for">https://github.com/antyakushev/postcss-for</a>
</li></ul><p><strong>Note</strong>: the <a href="https://github.com/antyakushev/postcss-for">postcss-for</a> plugin is another that <em>must</em> be executed before <a href="https://github.com/postcss/postcss-nested" rel="external" target="_blank">postcss-nested</a> and <a href="https://github.com/postcss/postcss-simple-vars" rel="external" target="_blank">postcss-simple-vars</a>.<br></p><p>Install the <a href="https://github.com/antyakushev/postcss-for">postcss-for</a> plugin, then test it’s working as expected by adding this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@for $i from 1 to 3 {
p:nth-of-type($i) {
margin-left: calc( 100% / $i );
}
}</pre><p>It should compile to give you:</p><pre class="brush: css noskimlinks noskimwords">p:nth-of-type(1) {
margin-left: calc( 100% / 1 );
}
p:nth-of-type(2) {
margin-left: calc( 100% / 2 );
}
p:nth-of-type(3) {
margin-left: calc( 100% / 3 );
}</pre><p>Once again, the plugin we’re using to add <code class="inline">@for</code> loops is the same as is used in PreCSS, so for extra information on its syntax check out the “Loops” section in the previous tutorial.<br></p><h3><strong>Other “for” Loop Plugin Options:</strong></h3><ul><li>Fork of postcss-for by Anton Yakushev: <a href="https://github.com/xori/postcss-for">https://github.com/xori/postcss-for</a>
</li></ul><p>The <a href="https://github.com/antyakushev/postcss-for">postcss-for</a> plugin has to be run before <a href="https://github.com/postcss/postcss-simple-vars" rel="external" target="_blank">postcss-simple-vars</a>, which means there’s no way to use variables to set the range you want your <code class="inline">@for</code> loop to iterate through. </p><p>If this is a problem, you can instead use <a href="https://github.com/xori/postcss-for" rel="external" target="_blank">this fork</a> of the postcss-for plugin that should instead be loaded <em>after</em> the postcss-simple-vars plugins. </p><p>Because it runs after variables are evaluated, you are free to use variables to set the range you want your <code class="inline">@for</code> loop to iterate through, like this:</p><pre class="brush: css noskimlinks noskimwords">@from: 1;
@count: 3;
@for $i from @from to @count {
p:nth-of-type($i) {
margin-left: calc( 100% / $i );
}
}</pre><h2>Add Variables<br>
</h2><p>We’re going to be adding two kinds of variables to our preprocessor, both of which can be very handy. The first kind uses Sass-like syntax, and the second uses the syntax of <a href="https://drafts.csswg.org/css-variables/" rel="external" target="_blank">CSS custom properties</a>, otherwise known as CSS variables.</p><h3><strong>Variables Plugins Used:</strong></h3><ul>
<li>postcss-simple-vars by Andrey Sitnik: <a href="https://github.com/postcss/postcss-simple-vars">https://github.com/postcss/postcss-simple-vars</a>
</li>
<li>postcss-css-variables by Eric Eastwood: <a href="https://github.com/MadLittleMods/postcss-css-variables">https://github.com/MadLittleMods/postcss-css-variables</a>
</li>
</ul><p>Install these two plugins, then we’ll test each one at a time.</p><p>First, we’ll test the Sass-like syntax of postcss-simple-vars. Open up the “_vars.css” file you made earlier, delete its contents and add the following code:</p><pre class="brush: css noskimlinks noskimwords">$default_padding: 1rem;</pre><p>Add the following to your “src/style.css” file and recompile:<br></p><pre class="brush: css noskimlinks noskimwords">.post {
padding: $default_padding;
}</pre><p>It should compile to give you:</p><pre class="brush: css noskimlinks noskimwords">.post {
padding: 1rem;
}</pre><p>Now we’ll test the CSS custom properties like syntax of postcss-css-variables. Add the following code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">:root {
--h1_font_size: 3rem;
}
h1 {
font-size: var(--h1_font_size);
}
@media ( max-width: 75rem ){
h1 {
--h1_font_size: 4vw;
}
}</pre><p>It should compile into:</p><pre class="brush: css noskimlinks noskimwords">h1 {
font-size: 3rem;
}
@media ( max-width: 75rem ) {
h1 {
font-size: 4vw;
}
}</pre><p>Notice that when using CSS variables, we only had to change the value of the <code class="inline">--h1_font_size</code> variable inside the media query and it automatically output the associated <code class="inline">font-size</code> property. This is particularly useful functionality.</p><h3><strong>Why Use Both Kinds of Variables?</strong></h3><p>Before I go on I’ll just briefly mention again, that the approach taken in this tutorial is not the approach you <em>have</em> to take. If you want to use one kind of variable and not the other, that’s completely fine.</p><p>From my perspective, the reason I like to use both kinds of variables is I use them in two different ways. I will typically use the CSS custom properties syntax in my main stylesheet, while I use Sass-like variables in my partial files.</p><p>This lets me set out CSS custom properties for the type of variables I might actually use in a live project if/when they become well supported across browsers. As you saw in the above example, they also have certain functionality that Sass-like variables do not.</p><p>Meanwhile, I can use Sass-like variables for things that don’t belong in a live stylesheet, especially those that exist purely to be processed through through things like each loops, conditionals and other transformations.</p><h3>Other Variables Plugin Options:</h3><ul><li>postcss-advanced-variables by Jonathan Neal: <a href="https://github.com/jonathantneal/postcss-advanced-variables">https://github.com/jonathantneal/postcss-advanced-variables</a>
</li></ul><p>As an alternative to using postcss-simple-vars you might like to consider using <a href="https://github.com/jonathantneal/postcss-advanced-variables">postcss-advanced-variables</a>, the plugin used as part of the PreCSS pack. </p><p>This is also an excellent option, with the primary difference being it handles conditionals, loops and variables all in the same plugin. For me, the reason I currently choose postcss-simple-vars is I prefer to have conditionals coming from a separate plugin; postcss-conditionals which we’ll cover shortly.</p><ul><li>postcss-custom-properties by Maxime Thirouin: <a href="https://github.com/postcss/postcss-custom-properties">https://github.com/postcss/postcss-custom-properties</a>
</li></ul><p>Instead of using postcss-css-variables, you might prefer <a href="https://github.com/postcss/postcss-custom-properties">postcss-custom-properties</a>. </p><p>The essential difference between the two is postcss-custom-properties conforms strictly to the <a href="http://www.w3.org/TR/css-variables/" rel="external" target="_blank">W3C spec for custom properties</a> so you can be confident that you are writing only correct future CSS. On the other hand postcss-css-variables offers extra functionality, but in doing so it does not claim to have complete parity with spec.</p><p>I personally choose postcss-css-variables because I am using it in the context of preprocessing where I write a lot of non-spec code anyway. As such I’d rather have the added functionality over 100% spec compliance.</p><p>However, if you’re using variables in the context of writing future CSS, you might find postcss-custom-properties is a better fit for you.</p><h2>Add “each” Loops</h2><h3><strong>“each” Loop Plugin Used:</strong></h3><ul><li>postcss-each by Alexander Madyankin: <a href="https://github.com/outpunk/postcss-each">https://github.com/outpunk/postcss-each</a>
</li></ul><p>Install the <a href="https://github.com/outpunk/postcss-each">postcss-each</a> plugin then add this variable code to your “_vars.css” file:</p><pre class="brush: css noskimlinks noskimwords">$social: twitter, facebook, youtube;</pre><p>This code defines a list, stored in the <code class="inline">$social</code> variable.</p><p>Now we’re going to create an <code class="inline">@each</code> loop to iterate through the values stored in our <code class="inline">$social</code> variable. Add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@each $icon in ($social){
.icon-$(icon) {
background: url('img/$(icon).png');
}
}</pre><p>Our <code class="inline">@each</code> loop is now ready, but before we can compile it we need to make a little configuration change to the options of postcss-simple-vars. </p><p>You’ll notice that in the code above we’re using <code class="inline">$icon</code> to represent the current value we’re iterating through. Some difficulty can arise from this because the postcss-simple-vars plugin looks for the <code class="inline">$</code> sign in order to identify variables.</p><p>This means it will see <code class="inline">$icon</code>, think it’s a variable, try to process it, then see it doesn’t have a value. That will make it stop compiling and log an error to the console that it’s discovered an undefined variable.</p><p>To resolve this, we want to add the option <code class="inline">silent: true</code> to our options for the plugin. This means that if it discovers an undefined variable it won’t stop compiling to log an error, it will just carry on. Hence it won’t be bothered by the presence <code class="inline">$icon</code> in our <code class="inline">@each</code> loop and we’ll be able to compile successfully.</p><p>In the processors array of your Gulpfile or Gruntfile, set the option:</p><pre class="brush: javascript noskimlinks noskimwords">/* Gulpfile */
simple_vars({silent: true})
/* Gruntfile */
require('postcss-simple-vars')({silent: true})</pre><p>Now compile your CSS and you should get:<br></p><pre class="brush: css noskimlinks noskimwords">.icon-twitter {
background: url('img/twitter.png');
}
.icon-facebook {
background: url('img/facebook.png');
}
.icon-youtube {
background: url('img/youtube.png');
}</pre><h3>Other “each” Loop Plugin Options:</h3><ul><li>postcss-advanced-variables by Jonathan Neal: <a href="https://github.com/jonathantneal/postcss-advanced-variables">https://github.com/jonathantneal/postcss-advanced-variables</a>
</li></ul><p>As mentioned earlier, postcss-advanced-variables is another excellent plugin option that handles variables, loops and conditionals all in one.</p><h2>Add Conditionals</h2><h3><strong>Conditionals Plugin Used:</strong></h3><ul><li>postcss-conditionals by Andy Jansson: <a href="https://github.com/andyjansson/postcss-conditionals">https://github.com/andyjansson/postcss-conditionals</a>
</li></ul><p>I mentioned previously that this plugin is my preference for handling conditionals. This is because I have found it is able to handle more complex conditional checks. It includes support for <code class="inline">@else if</code> syntax, meaning you can test against more conditions in a single piece of code.</p><p>After installing the postcss-conditionals plugin, test it out by adding this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">$column_count: 3;
.column {
@if $column_count == 3 {
width: 33%;
float: left;
} @else if $column_count == 2 {
width: 50%;
float: left;
} @else {
width: 100%;
}
}</pre><p>This code will check on the value we’ve set in the variable <code class="inline">@column_count</code> and will output different width and float values depending on what it finds. It works in the same way as the code we used in the previous preprocessing tutorial, but now that we have the ability to use <code class="inline">@else if</code> lines we’ve been able to increase the number of conditions we’re testing from two to three.</p><p>After recompiling this should give you:</p><pre class="brush: css noskimlinks noskimwords">.column {
width: 33%;
float: left
}</pre><p>Try changing <code class="inline">$column_count</code> to <code class="inline">2</code> or <code class="inline">1</code> and compiling again to see how it changes the CSS output.</p><p>We can also use these types of conditionals well inside mixins, for which we added support earlier. For example, we can create a mixin to generate column layout code like so:</p><pre class="brush: css noskimlinks noskimwords">@define-mixin columns $count {
@if $count == 3 {
width: 33%;
float: left;
} @else if $count == 2 {
width: 50%;
float: left;
} @else {
width: 100%;
}
}
.another_column {
@mixin columns 2;
}</pre><p>This will give you the output:</p><pre class="brush: css noskimlinks noskimwords">.another_column {
width: 50%;
float: left;
}</pre><h3>Other Conditionals Options:</h3><ul><li>postcss-advanced-variables by Jonathan Neal: <a href="https://github.com/jonathantneal/postcss-advanced-variables">https://github.com/jonathantneal/postcss-advanced-variables</a>
</li></ul><p>As mentioned earlier, postcss-advanced-variables is another excellent plugin option that handles variables, loops and conditionals all in one.</p><h2>Add Calc() for Math</h2><h3><strong>Calc() Plugin Used:</strong></h3><ul><li>postcss-calc by Maxime Thirouin: <a href="https://github.com/postcss/postcss-calc">https://github.com/postcss/postcss-calc</a>
</li></ul><p>In a previous tutorial we used postcss-calc, via cssnano, to help make instances of <code class="inline">calc()</code> use more efficient. In the context of preprocessing, however, it can be very useful wherever we might want to use math in our stylesheets. </p><p>Go ahead and install postcss-calc, then we’re going to test it out by making the column generation mixin we added above more efficient. </p><p>Right now we’re using conditionals to check if the mixin’s <code class="inline">$count</code> argument is set to either <code class="inline">1</code>, <code class="inline">2</code> or <code class="inline">3</code> then outputting a corresponding pre-calculated width. Instead, we’ll use <code class="inline">calc()</code> to automatically output the right width for our column code, no matter what number is passed through the mixin.</p><p>Add to your “src/style.css” file:<br></p><pre class="brush: css noskimlinks noskimwords">@define-mixin columns_calc $count {
width: calc( 100% / $count );
@if $count &gt; 1 {
float: left;
}
}
.column_calculated {
@mixin columns_calc 2;
}</pre><p>Instead of hard coding the percentage widths we’d need for certain numbers of columns, we’re now calculating it on the fly. </p><p>The postcss-calc plugin will convert <code class="inline">width: calc( 100% / $count );</code> into a static amount depending on the value passed when we call the mixin, in this case <code class="inline">2</code>.</p><p>Recompile your code and you should see this output:</p><pre class="brush: css noskimlinks noskimwords">.column_calculated {
width: 50%;
float: left;
}</pre><p><strong>Note</strong>: Wherever postcss-calc can resolve <code class="inline">calc()</code> to a static value it will output it into your code. If it can’t, it will change nothing, so you can still use <code class="inline">calc()</code> for values that need to be handled by the browser at runtime.</p><h2>Add Nesting</h2><h3><strong>Nesting Plugin Used:</strong></h3><ul><li>postcss-nested by Andrey Sitnik: <a href="https://github.com/postcss/postcss-nested">https://github.com/postcss/postcss-nested</a>
</li></ul><p>For nesting we’re using the same plugin as is used in the PreCSS pack, so you can refer back to the previous tutorial for full information on syntax. </p><p>Install <a href="https://github.com/postcss/postcss-nested">postcss-nested</a> then test that everything is working properly by compiling this code:</p><pre class="brush: css noskimlinks noskimwords">.menu {
width: 100%;
a {
text-decoration: none;
}
}</pre><p>Your resulting CSS should be:</p><pre class="brush: css noskimlinks noskimwords">.menu {
width: 100%;
}
.menu a {
text-decoration: none;
}</pre><h2>Add Extends</h2><h3><strong>Extends Plugin Used:</strong></h3><ul><li>postcss-sass-extend by Jonathan Neal: <a href="https://github.com/jonathantneal/postcss-sass-extend">https://github.com/jonathantneal/postcss-sass-extend</a>
</li></ul><p>For extends we’ll be using the <a href="https://github.com/jonathantneal/postcss-sass-extend">postcss-sass-extend</a> plugin. It will give us different syntax to use than that we covered in our previous tutorial on working with PreCSS. Instead of extends being defined with <code class="inline">@define-extend extend_name {...}</code> they are defined with <code class="inline">%extend_name {...}</code>.</p><p>They are still used with the essentially the same syntax of <code class="inline">@extend %extend_name;</code>.</p><p>Note that the postcss-sass-extend plugin does actually ship with PreCSS, however I assume it doesn’t load by default as when I attempted to use the required syntax it did not compile.</p><p>After installing postcss-sass-extend into your project, test it out with the following code:</p><pre class="brush: css noskimlinks noskimwords">%rounded_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}
.blue_button {
@extend %rounded_button;
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
@extend %rounded_button;
border-color: #C41A1E;
background-color: #FF2025;
}</pre><p>It should compile into:</p><pre class="brush: css noskimlinks noskimwords">.blue_button, .red_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}
.blue_button {
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
border-color: #C41A1E;
background-color: #FF2025;
}</pre><h3><strong>Other Extend Plugin Options:</strong></h3><ul>
<li>postcss-extend: <a href="https://github.com/travco/postcss-extend">https://github.com/travco/postcss-extend</a>
</li>
<li>postcss-simple-extend: <a href="https://github.com/davidtheclark/postcss-simple-extend">https://github.com/davidtheclark/postcss-simple-extend</a>
</li>
</ul><h2>Extras</h2><p>So far we’ve covered what could be considered the core features common to most preprocessors. However, there are still even more plugins available to offer extra features; some of these features are found in other preprocessors, and some you have to go to PostCSS to find. We’ll go over these extra options briefly now.</p><h3>Color Manipulation</h3><h4><strong>Plugins:</strong></h4><ul>
<li>postcss-color-function by Maxime Thirouin: <a href="https://github.com/postcss/postcss-color-function">https://github.com/postcss/postcss-color-function</a>
</li>
<li>postcss-color-alpha by Ivan Vlasenko: <a href="https://github.com/avanes/postcss-color-alpha">https://github.com/avanes/postcss-color-alpha</a>
</li>
<li>postcss-color-scale by Kristofer Joseph: <a href="https://github.com/kristoferjoseph/postcss-color-scale">https://github.com/kristoferjoseph/postcss-color-scale</a>
</li>
</ul><p>The ability to tweak colors can be one of the most useful features found in preprocessors. There are actually several color plugins for PostCSS, but these are three that find themselves particularly at home in a preprocessing setup. They allow for various color transformations including lightening, darkening, saturating, adding alpha values and more.</p><h3>Property Definitions<br>
</h3><h4><strong>Plugin:</strong></h4><ul><li>postcss-define-property by Dale Eidd: <a href="https://github.com/daleeidd/postcss-define-property">https://github.com/daleeidd/postcss-define-property</a>
</li></ul><p>The functionality offered by this plugin could be compared to the seamless mixins of Stylus, whereby, rather than using a syntax like <code class="inline">@mixin</code>, you define chunks of code in such a way that they can subsequently be used in code in the same way as a native property, e.g. </p><pre class="brush: css noskimlinks noskimwords">/* Define a property */
size: $size {
height: $size;
width: $size;
}
/* Use it like a native property */
.square {
size: 50px;
}</pre><p>The plugin can also be used to redefine native properties to suit your needs.</p><h3>Property Lookup</h3><h4><strong>Plugin:</strong></h4><ul><li>postcss-property-lookup by Simon Smith: <a href="https://github.com/simonsmith/postcss-property-lookup">https://github.com/simonsmith/postcss-property-lookup</a>
</li></ul><p>Property lookup is a feature found in Stylus that can be very handy. It allows you to lookup the value of a property from within the same style. For example, you might set a right margin to match the left with: <code class="inline">margin-left: 20px; margin-right: @margin-left;</code></p><h3>Nested Properties</h3><h4>Plugin:</h4><ul><li>postcss-nested-props by Jed Mao: <a href="https://github.com/jedmao/postcss-nested-props">https://github.com/jedmao/postcss-nested-props</a>
</li></ul><p>While the regular nesting we covered above unwraps selectors, the postcss-nested-props plugin unwraps nested properties, for example:</p><pre class="brush: css noskimlinks noskimwords">/* Origincal code */
.element {
border: {
width: 1px;
style: solid;
color: #ccc;
}
}
/* After processing */
.element {
border-width: 1px;
border-style: solid;
border-color: #ccc;
}</pre><h3>Matching</h3><h4><strong>Plugin:</strong></h4><ul><li>postcss-match by Ryan Tsao: <a href="https://github.com/rtsao/postcss-match">https://github.com/rtsao/postcss-match</a>
</li></ul><p>Matching gives you another way to perform conditional checks, this time using Rust like pattern matching, something similar to switch statements in JavaScript or PHP. This can give you a more efficient way to check multiple conditions than writing many <code class="inline">@if else</code> checks.</p><h3>CSS Sprite Generation</h3><h4><strong>Plugin:</strong></h4><ul><li>postcss-sprites by Viktor Vasilev: <a href="https://github.com/2createStudio/postcss-sprites">https://github.com/2createStudio/postcss-sprites</a>
</li></ul><p>CSS sprite generation, a popular feature in Compass, can also be done through the postcss-sprites plugin. The plugin will scan your CSS for images, combine those images into a sprite sheet, and update your code as required in order to display from the new sprite sheet correctly.</p><h3>Lots More Choices</h3><p>There is currently a really robust list of language extension plugins to choose from, more than we can cover here, so check out the full list at: <a href="https://github.com/postcss/postcss#language-extensions">https://github.com/postcss/postcss#language-extensions</a></p><h2>Coming Soon: Alternative Syntaxes</h2><p>For many people, the ability to write in terse, efficient syntax (typically sans semicolons and curly braces) is one of the big appeals of preprocessors like Stylus or Sass. The newly released version 5.0 of PostCSS now supports custom parsers which will enable new syntaxes to be supported. <a href="https://github.com/postcss/postcss/issues/495" rel="external" target="_blank">SugarSS</a> is to be the terse syntax parser, and discussions are currently open on how this syntax will be structured.</p><h2>You Can Always Add Your Own</h2><p>PostCSS is still relatively new and you may find there is something you want to achieve with your custom preprocessor for which there’s currently no plugin. The beauty of this modular ecosystem is you have the option to solve that problem yourself by creating your own plugin. Anyone can do it, and the barrier to entry is far lower than were you to try and add your own functionality to Stylus, Sass or LESS. We’ll learn how in a later tutorial.</p><h2>In the Next Tutorial</h2><p>You don’t have to choose between PreCSS and rolling your own preprocessor if you want to use PostCSS. You can actually opt out of any PostCSS-based preprocessing entirely if you choose, instead using it side by side with your favorite preprocessor.</p><p>In the next tutorial we’ll learn how to use PostCSS in conjunction with Stylus, Sass or LESS. See you there!</p>2015-10-22T16:41:45.000Z2015-10-22T16:41:45.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24583PostCSS Deep Dive: Preprocessing with “PreCSS”<p>In the last <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-cross-browser-compatibility--cms-24567" target="_self">two</a> <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568" target="_self">tutorials</a> we looked at ways to use PreCSS on completed stylesheets to enhance their cross browser compatibility and optimization, essentially as a <em>post</em>-processor. In this tutorial you’ll learn to use PostCSS as a <em>pre</em>-processor, in the same way you would use Stylus, Sass or LESS.</p><p>There are two main ways you can go about using PostCSS for preprocessing. One is to select all your own plugins to add the preprocessor functionality you want, and the other is to install a pack of preselected plugins so you’re ready to go right away.</p><p>We’ll start with the quickest and easiest approach, installing the excellent <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">PreCSS</a> pack of plugins, created by Jonathan Neal. In the tutorial after this we’ll move onto how you can put together your own preprocessor, using only the functionality you want.</p><p>This tutorial will assume you have some degree of familiarity with the features commonly found in preprocessors like Stylus, Sass or LESS. That’s purely because we’ll be focusing on <em>how</em> you can use these same types of features via PostCSS, rather than <em>what</em> the features actually do. That said though, even if you’ve never used a preprocessor before, this might be the perfect place to start.</p><h2>Try Out PreCSS Live</h2><p>We’ll go through how to setup a Gulp or Grunt project using PreCSS in the next section, however, if you would like to take a shortcut, (just for now), you can alternatively use the <a href="https://jonathantneal.github.io/precss/" rel="external" target="_blank">live demo playground</a> to try out the code we’ll run through in this tutorial. Code can be typed into the left window, and it will automatically compile for you and display in the right window.</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/30/posts/24583/image/window.jpg"><figcaption>PreCSS Live Editor: <a href="https://jonathantneal.github.io/precss/">https://jonathantneal.github.io/precss</a></figcaption></figure><h2>Setup Your Project</h2><p>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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/postcss-deep-dive-preprocessing-with-precss-/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, and extract either the provided Gulp or Grunt starter project into an empty project folder. <br></p><p>Then, with a terminal or command prompt pointed at the folder, run the command<code class="inline">npm install</code>.</p><h3>Install PreCSS</h3><p>Whether you’re using Gulp or Grunt, install <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">PreCSS</a> into your project with the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install precss --save-dev</pre><h3>Load as a Gulp Plugin</h3><p>If you’re using Gulp, add this variable under the variables already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var precss = require('precss');</pre><p>Now add the new variable name into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
precss
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load as a Grunt Plugin</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('precss')()
]</pre><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><p>You now have everything you need to use PreCSS installed and ready to go. This means we’re ready to start stepping through the some of the preprocessing capabilities of PreCSS and how they can be used.<br></p><h2>Preprocessing via “PreCSS”</h2><p>Generally speaking, PreCSS syntax is most similar to that of Sass. However it does use some of its own unique approaches, which we’ll cover as we go along. </p><p><strong>Note</strong>: because of the Sass-like syntax of PreCSS, you’ll find that a Sass syntax highlighter will work best for you in your favorite text editor.</p><h3>Nesting</h3><p>Nesting is something common to all three of the major preprocessors, i.e. Stylus, Sass and LESS, and it’s also present in PreCSS. Nesting in PreCSS is done in the same way as in Sass and LESS, by placing selectors inside the curly brackets of other selectors.</p><p>The ability to use the <code class="inline">&amp;</code> symbol to have the parent selector duplicated into the child selector also works in the same way in PreCSS as in other preprocessors.</p><p>Try adding the following nested code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.menu {
width: 100%;
a {
text-decoration: none;
}
&amp;::before {
content: '';
}
}</pre><p>Compile your CSS with <code class="inline">gulp css</code> or <code class="inline">grunt postcss</code> and your “dest/style.css” file should have evaluated the nested code into the following:</p><pre class="brush: css noskimlinks noskimwords">.menu {
width: 100%;
}
.menu a {
text-decoration: none;
}
.menu::before {
content: '';
}</pre><h3>Variables</h3><p>Variables are another type of functionality common to all preprocessors, and they are included in PreCSS. The only thing typically differing between each preprocessor is the syntax to denote variables.</p><ul>
<li>LESS variables begin with an <code class="inline">@</code> symbol and place a <code class="inline">:</code> before the value. </li>
<li>Stylus variables can optionally use a <code class="inline">$</code> symbol and place an <code class="inline">=</code> sign before the value. </li>
<li>Sass variables use a <code class="inline">$</code> symbol and place a <code class="inline">:</code> before the value.</li>
</ul><p>In keeping with the PreCSS tendency to uses Sass like syntax, it too places a <code class="inline">$</code> before the variable name and a <code class="inline">:</code> before the value. </p><p>Try out using PreCSS variables by adding this to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">$text_color: #232323;
body {
color: $text_color;
}</pre><p>After recompiling you should see this resulting code:</p><pre class="brush: css noskimlinks noskimwords">body {
color: #232323;
}</pre><h3>Conditionals</h3><p>Conditionals, i.e. <code class="inline">if</code> and <code class="inline">else</code> logic, are a feature that is very strong in both Sass and Stylus. LESS offers <a href="https://code.tutsplus.com/courses/less-is-more/lessons/guarded-mixins" target="_self">guarded mixins</a>, but they don’t offer quite the same degree of power. Conditionals are present in PreCSS and follow the same syntax as Sass, using <code class="inline">@if</code> and <code class="inline">@else</code>. </p><p>Add this example code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">$column_layout: 2;
.column {
@if $column_layout == 2 {
width: 50%;
float: left;
} @else {
width: 100%;
}
}</pre><p>In the above example we’re having a <code class="inline">.column</code> class output differently depending on if we want a one column layout, or a two column layout. We have the <code class="inline">$column_layout</code> variable set to <code class="inline">2</code>, meaning we should see <code class="inline">width: 50%; float: left;</code> output into our class.</p><p>Compile your file, and you should see the following in your “dest/style.css” file.</p><pre class="brush: css noskimlinks noskimwords">.column {
width: 50%;
float: left
}</pre><p><strong>Note</strong>: the <a href="https://github.com/jonathantneal/postcss-advanced-variables" rel="external" target="_blank">postcss-advanced-variables</a> plugin that provides this conditionals functionality is still quite new, and I have encountered some unexpected output when using it for more complex conditionals, however, I’m sure it will be updated in the near future. </p><p>There is an alternative plugin that can be used for conditionals named <a href="https://github.com/andyjansson/postcss-conditionals" rel="external" target="_blank">postcss-conditionals</a>. We’ll cover how you can use that plugin (if you choose) in the next tutorial, “Rolling Your Own Preprocessor”.</p><h3>Loops - <code class="inline">@for</code> and <code class="inline">@each</code>
</h3><p>There are two types of loops available in PreCSS, the <code class="inline">@for</code> and <code class="inline">@each</code> loops. Both of these use an approach that is just like Sass. “For” loops let you cycle through a numerical counter, while “each” loops let you cycle through a list of items.</p><h4>
<code class="inline">@for</code> Loops</h4><p>In a <code class="inline">@for</code> loop there is a “counter” variable that keeps track of where you are in cycling through your numeric counter, typically set as <code class="inline">$i</code>. For example, when iterating from 1 to 3 there will be three loops; in the first <code class="inline">$i</code> will equal <code class="inline">1</code>, the second it will equal <code class="inline">2</code> and the third it will equal <code class="inline">3</code>. </p><p>This <code class="inline">$i</code> counter variable can be interpolated into both selectors and rules, which can be very handy for things like generating <code class="inline">nth-of-type()</code> rules and calculating widths.</p><p>Add this code to your “src/style.css” file to try out a <code class="inline">@for</code> loop:</p><pre class="brush: css noskimlinks noskimwords">@for $i from 1 to 3 {
p:nth-of-type($i) {
margin-left: calc( 100% / $i );
}
}</pre><p>After compilation you should see this code expanded out to:</p><pre class="brush: css noskimlinks noskimwords">p:nth-of-type(1) {
margin-left: calc( 100% / 1 );
}
p:nth-of-type(2) {
margin-left: calc( 100% / 2 );
}
p:nth-of-type(3) {
margin-left: calc( 100% / 3 );
}</pre><p><strong>Note</strong>: numbers <code class="inline">1</code>, <code class="inline">2</code> and <code class="inline">3</code> have been inserted into each of the above styles.</p><h4>
<code class="inline">@each</code> Loops</h4><p>An <code class="inline">@each</code> loop cycles through a list of items instead of numbers. As with <code class="inline">@for</code> loops, the variable representing the loop’s current item can be interpolated into selectors and rules. Note that to interpolate into a string, you need to insert a set of brackets into the variable name in the format <code class="inline">$(var)</code>. </p><p>Give using PreCSS <code class="inline">@each</code> loops a go by adding the following example code:</p><pre class="brush: css noskimlinks noskimwords">$social: twitter, facebook, youtube;
@each $icon in ($social){
.icon-$(icon) {
background: url('img/$(icon).png');
}
}</pre><p>After compilation you should see the following CSS has been generated:</p><pre class="brush: css noskimlinks noskimwords">.icon-twitter {
background: url('img/twitter.png');
}
.icon-facebook {
background: url('img/facebook.png');
}
.icon-youtube {
background: url('img/youtube.png');
}</pre><h3>Mixins</h3><p>The syntax for mixin creation is one aspect of PreCSS that’s a little different to Sass. </p><p>In Sass, to define a mixin you use the syntax <code class="inline">@mixin mixin_name($arg1, $arg2) {...}</code> and then use it with <code class="inline">@include mixin_name(pass_arg1, pass_arg2);</code>.</p><p>In PreCSS, on the other hand, you define a mixin with the syntax <code class="inline">@define-mixin mixin_name $arg1, $arg2 {...}</code> and use it with <code class="inline">@mixin mixin_name pass_arg1, pass_arg2;</code>. </p><p>Add this example to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@define-mixin icon $network, $color {
.button.$(network) {
background-image: url('img/$(network).png');
background-color: $color;
}
}
@mixin icon twitter, blue;
@mixin icon youtube, red;</pre><p>On compilation you should see:</p><pre class="brush: css noskimlinks noskimwords">.button.twitter {
background-image: url('img/twitter.png');
background-color: blue;
}
.button.youtube {
background-image: url('img/youtube.png');
background-color: red;
}</pre><p><strong>Note</strong>: arguments passed through the mixin can be interpolated into selectors and strings with the same approach as mentioned in <code class="inline">@each</code> loops above; with the format <code class="inline">$(var)</code>.</p><h4>Using @mixin-content</h4><p>As well as using mixins in the way shown above, they can also be set to consume blocks of content passed when calling the mixin. This is essentially the same process as with Sass’ <code class="inline">@content</code>. </p><p>For instance, modify the mixin from the above example, placing <code class="inline">@mixin-content</code> where you want a passed block of content to appear, like so:</p><pre class="brush: css noskimlinks noskimwords">@define-mixin icon $network, $color {
.button.$(network) {
background-image: url('img/$(network).png');
background-color: $color;
@mixin-content;
}
}</pre><p>When a mixin incorporating <code class="inline">@mixin-content</code> is used, it must be placed with curly brackets, rather than on a single line ending with a <code class="inline">;</code>, or it will fail to compile.</p><p>Update your code so your mixin calls look like this:</p><pre class="brush: css noskimlinks noskimwords">@mixin icon twitter, blue {
width: 3rem;
}
@mixin icon youtube, red {
width: 4rem;
}</pre><p>After compilation, this should yield the following code - notice the inclusion of the <code class="inline">width</code> content passed through each use of the mixin:</p><pre class="brush: css noskimlinks noskimwords">.button.twitter {
background-image: url('img/twitter.png');
background-color: blue;
width: 3rem;
}
.button.youtube {
background-image: url('img/youtube.png');
background-color: red;
width: 4rem;
}</pre><h3>Extends</h3><p>Extends are similar to mixins in a sense, in that they’re designed to allow you to reuse blocks of code. However, the idea behind “extends” is to create a base set of code you know you’re going to use in the exact same way multiple times for a certain type of element. You can then subsequently extend on that base with additional, non-default code.</p><p>In PreCSS, the syntax to define an extend is <code class="inline">@define-extend extend_name {...}</code>.</p><p>In your “src/style.css” file, define an extend containing the base styles for a rounded button like so:</p><pre class="brush: css noskimlinks noskimwords">@define-extend rounded_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}</pre><p>This default set of styles is now ready be extended on with extra code, for example, setting things like <code class="inline">background-color</code> and <code class="inline">border-color</code>. This is done by using the syntax <code class="inline">@extend extend_name;</code> to import the base styles defined in the extend. </p><p>Add this example code, underneath the code you just added:</p><pre class="brush: css noskimlinks noskimwords">.blue_button {
@extend rounded_button;
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
@extend rounded_button;
border-color: #C41A1E;
background-color: #FF2025;
}</pre><p>Where the <code class="inline">@extend rounded_button;</code> line is used, the entire contents of the extend will be inserted.</p><p>Compile your styles and you should get:</p><pre class="brush: css noskimlinks noskimwords">.blue_button,
.red_button {
border-radius: 0.5rem;
padding: 1em;
border-width: 0.0625rem;
border-style: solid;
}
.blue_button {
border-color: #2F74D1;
background-color: #3B8EFF;
}
.red_button {
border-color: #C41A1E;
background-color: #FF2025;
}</pre><p>Note also that the styles common to the <code class="inline">.blue_button</code> and <code class="inline">.red_button</code> class have been combined for efficiency.</p><h3>Imports</h3><p>The plugin used for inlining stylesheets via <code class="inline">@import</code> is the same one we covered in the previous tutorial of this series: <a href="http://webdesign.tutsplus.com/tutorials/using-postcss-for-minification-and-optimization--cms-24568" target="_self">For Minification and Optimization</a>. For a rundown on how it works head over and have a read of the sectioned headed “Inline / Combine Files with @import”.</p><p>In the context of using PostCSS as a preprocessor, imports become even more useful as they give you the option of setting up partials, something you might be used to from other preprocessing solutions. For example, you might setup a “partials” folder, separate your project into logically discrete partial files then import them like so:</p><pre class="brush: css noskimlinks noskimwords">@import "partials/_variables.css";
@import "partials/_utilities.css";
@import "partials/_mixins.css";
@import "partials/_extends.css";</pre><h2>Let’s Recap</h2><p>I hope you now have some insights into how powerful PostCSS can be as a preprocessor by way of the PreCSS pack. To summarize what we covered above:</p><ul>
<li>You can try out PreCSS live at <a href="https://jonathantneal.github.io/precss">https://jonathantneal.github.io/precss</a>.</li>
<li>Nesting in PreCSS works the same way as Sass and LESS.</li>
<li>Variables in PreCSS use the same syntax as Sass.</li>
<li>Conditionals are present in PreCSS, using the syntax @if and @else.</li>
<li>@for and @each loops are available.</li>
<li>PreCSS mixins are defined with the syntax:<br><code class="inline">@define-mixin mixin_name $arg1, $arg2 {...}</code>
</li>
<li>PreCSS mixins are used with the syntax:<br><code class="inline">@mixin mixin_name pass_arg1, pass_arg2;</code>
</li>
<li>
<code class="inline">@mixin-content</code> can be used in the same way as Sass' <code class="inline">@content</code>
</li>
<li>Extends in PreCSS are defined with the syntax:<br><code class="inline">@define-extend extend_name {...}</code><br>
</li>
<li>Extends are used with the syntax:<br><code class="inline">@extend extend_name;</code><br>
</li>
<li>
<code class="inline">@import</code> inlines external CSS files, particularly helpful for using partials</li>
</ul><h2>In the Next Tutorial<br>
</h2><p>PreCSS is a fantastic project, bringing together some excellent language extension plugins and making PostCSS-based preprocessing pretty much plug and play. It provides almost all of the functionality most preprocessor users have come to expect, and is a quick, “no fuss” way to get the PostCSS preprocessor ball rolling.</p><p>Using PreCSS is one of the two methods of PostCSS preprocessing we mentioned at the start of this tutorial. The other method is to setup your <em>own</em> preprocessor, hand picking the language extension plugins that suit your own projects or coding style. The trade off is it’s a little more setup, but in return you get the freedom to put together a preprocessor that works however you want it to.</p><p>You’ll learn how to do this in the next tutorial, “Roll Your Own Preprocessor”.</p>2015-10-21T13:03:44.000Z2015-10-21T13:03:44.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24568Using PostCSS for Minification and Optimization<p>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.</p><p>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.</p><p>You’ll learn how to:</p><ul>
<li>Combine multiple stylesheets into one via the <code class="inline">@import</code> rule, even if some of your stylesheets are coming from Bower components or npm modules, ensuring you need only a single <code class="inline">http</code> request to load your site’s CSS.</li>
<li>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.</li>
<li>Use the <a href="http://cssnano.co/" rel="external" target="_blank">cssnano</a> pack to perform all kinds of optimizations from stripping white space and comments to minifying certain types of code and much more.</li>
</ul><p>Let’s get started!</p><h2>Setup Your Project</h2><p>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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials</p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or</li>
<li><a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a></li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/using-postcss-for-minification-and-optimization/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, 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 <code class="inline">npm install</code>.<br></p><h2>Install Plugins</h2><p>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:</p><pre class="brush: bash noskimlinks noskimwords">npm install postcss-import css-mqpacker cssnano --save-dev</pre><p>Now the plugins are installed, let’s go ahead and load them into your project.</p><h3>Load Plugins via Gulp</h3><p>If you’re using Gulp, add these variables under the variables already in the file:</p><pre class="brush: javascript noskimlinks noskimwords">var atImport = require('postcss-import');
var mqpacker = require('css-mqpacker');
var cssnano = require('cssnano');</pre><p>Now add each of those new variable names into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
atImport,
mqpacker,
cssnano
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><h3>Load Plugins via Grunt</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('postcss-import')(),
require('css-mqpacker')(),
require('cssnano')()
]</pre><p>Do a quick test that everything is working by running the command <code class="inline">grunt postcss</code> then checking that a new “style.css” file has appeared in your project’s “dest” folder.</p><p>That has all the plugins installed and loaded, so let’s move onto learning how to use them for minification and optimization.<br></p><h2>Inline/Combine Files with @import</h2><p>Rather than individually loading multiple stylesheets, it’s more efficient wherever possible to combine your stylesheets into one. </p><p>For example, use of <a href="https://necolas.github.io/normalize.css/" rel="external" target="_blank">Normalize.css</a> is very common, but, if you load it as a standalone stylesheet before your main stylesheet, it requires multiple <code class="inline">http</code> requests, hence slowing down load time. </p><p>However if you use the <a href="https://github.com/postcss/postcss-import">postcss-import</a> plugin by Maxime Thirouin, you can combine Normalize.css into your main stylesheet, via use of the <code class="inline">@import</code> rule, giving you the same CSS with only one <code class="inline">http</code> request.</p><h3>@import then Inline Normalize.css</h3><p>Let’s go ahead and do this now, importing and then inlining Normalize.css into our project’s stylesheet. Start by downloading “normalize.css” into your project’s “src” folder, from <a href="https://necolas.github.io/normalize.css/">https://necolas.github.io/normalize.css/</a></p><p>At the top of your “src/style.css” file add the following line:</p><pre class="brush: css noskimlinks noskimwords">@import 'normalize.css';</pre><p>As you already have postcss-import installed, that’s all you have to do. It will see the <code class="inline">@import</code> rule and automatically inline the code from the normalize.css file into your stylesheet.</p><p>Compile your file, and when you look at your “dest/style.css” file you should see the entire contents of “normalize.css” therein:</p><pre class="brush: css noskimlinks noskimwords">/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;.......</pre><p>You can use this same process to combine as many separate stylesheets as you need to. Just place <code class="inline">@import</code> lines in your “src/style.css” file wherever you want the inlined code to be inserted.</p><h3>Automatic Bower Component and Node Module Discovery</h3><p>One very helpful feature of this plugin is its ability to automatically discover CSS files situated inside your “bower_components” or “node_modules” folder. </p><p>For example, rather than manually downloading “normalize.css” as we did above, you could instead just run the command <code class="inline">bower install normalize.css --save</code> in your project. This would automatically download the latest “normalize.css” file into the “bower_components/normalize.css” folder.</p><p><strong>Note</strong>: If you don’t have Bower setup on your computer <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-taming-3rd-party-packages--cms-23451" rel="external" target="_blank">learn how here</a>.</p><p>At the top of your stylesheet, you could now instead use this line:</p><pre class="brush: css noskimlinks noskimwords">@import 'normalize.css/normalize.css';</pre><p>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.</p><p>The same process can be followed for any stylesheets that are in your “node_modules” folder, meaning you can use either <a href="http://bower.io/" rel="external" target="_blank">Bower</a> or <a href="https://www.npmjs.com/" rel="external" target="_blank">npm</a> 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.</p><h3>Ways to Leverage @import Inlining</h3><p>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.</p><p>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:</p><ol>
<li>Duplicate original color stylesheet</li>
<li>Modify it with new color codes </li>
<li>Import the new color stylesheet into your project</li>
<li>Compile to create alternate colored stylesheet </li>
</ol><p>You could then repeat this process as many times as you wanted, making it efficient to create multiple color schemes for the same design. </p><p>Some projects use separate stylesheets to provide multiple color schemes like this, but in the process create slowdown from added <code class="inline">http</code> requests. With this approach you always end up with just one <code class="inline">http</code> request, despite having a lot of freedom in what might be included in your single stylesheet.<br></p><p>Read more about postcss-import at: <a href="https://github.com/postcss/postcss-import">https://github.com/postcss/postcss-import</a></p><h2>Combine Matching Media Queries</h2><p>The <a href="https://github.com/hail2u/node-css-mqpacker">css-mqpacker</a> 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.</p><p>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.</p><p>We’ll start with some layout code. We’ll add a <code class="inline">.column</code> class that will make two <code class="inline">50%</code> 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:</p><pre class="brush: css noskimlinks noskimwords">/* LAYOUT */
.column {
width: 50%;
float: left;
}
@media (max-width: 50rem) {
.column {
width: 100%;
float: none;
}
}</pre><p>Next we’ll add some visuals to set a gray border around our columns. The first column will have the class <code class="inline">.column_one</code> and the second will have the class <code class="inline">.column_two</code>. 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.</p><p>Add this code to your stylesheet as well:</p><pre class="brush: css noskimlinks noskimwords">/* 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;
}
}</pre><p>Now, recompile your “src/style.css” file and take a look at the resulting “dest/style.css” content. </p><p>As you can see in the code below, the css-mqpacker plugin has identified the two matching media queries, and combined them into one:<br></p><pre class="brush: css noskimlinks noskimwords">/* 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;
}
}</pre><p><strong>Note</strong>: 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 <code class="inline">cssnano</code> from your Gulpfile or Gruntfile’s <code class="inline">processors</code> array.</p><p>Read more about css-mqpacker at <a href="https://github.com/hail2u/node-css-mqpacker">https://github.com/hail2u/node-css-mqpacker</a></p><h2>cssnano Plugin Pack</h2><p>For comprehensive and multifaceted CSS optimization, the <a href="http://cssnano.co/" rel="external" target="_blank">cssnano</a> 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.</p><p>Among a long list of optimizations, it can:</p><ul>
<li>Strip whitespace and final semicolons</li>
<li>Remove comments</li>
<li>Optimize font weights</li>
<li>Discard duplicate rules</li>
<li>Optimize <code class="inline">calc()</code> use</li>
<li>Minify selectors</li>
<li>Minimize longhand properties</li>
<li>Merge rules</li>
</ul><p>We’re going to process some example code in your project that will see all of the above optimizations applied.</p><p>Add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.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;
}</pre><p>Then recompile your file. </p><p><strong>Note</strong>: you may wish to comment out any code you already had, so you can clearly see the results. </p><p>In your “dest/style.css” file you should now see the optimized code:</p><pre class="brush: css noskimlinks noskimwords">.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}</pre><p>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:</p><ul>
<li>Whitespace, comments and final semicolons are gone</li>
<li>
<code class="inline">font-weight: normal</code> and <code class="inline">font-weight: bold</code> are converted to <code class="inline">font-weight: 400</code> and <code class="inline">font-weight: 700</code>
</li>
<li> The second, repeated instance of the rule <code class="inline">font-weight: normal;</code> has been removed from the <code class="inline">.css_nano</code> style</li>
<li>The <code class="inline">calc()</code> property has been reduced to a static value</li>
<li>The selectors <code class="inline">.css_nano, .css_nano + p, [class*="css_nano"], .css_nano</code> have been minified to <code class="inline">.css_nano,.css_nano+p,[class*=css_nano]</code>
</li>
<li>The longhand properties <code class="inline">margin-top: 1rem; margin-bottom: 2rem; margin-left: 1.5rem; margin-right: 2.5rem;</code> have been reduced to <code class="inline">margin:1rem 2.5rem 2rem 1.5rem;</code>
</li>
<li>The <code class="inline">a</code> and <code class="inline">p</code> styles have been merged to share their common <code class="inline">font-weight: 700;</code> setting</li>
</ul><p>For a full list of optimizations cssnano provides check out: <a href="http://cssnano.co/optimisations/">http://cssnano.co/optimisations/</a></p><h3>Configuring Options and Disabling Modules</h3><p>There are several independent plugins employed by the cssnano pack, and you may wish to configure settings for, or fully disable, some of them.</p><p>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:</p><pre class="brush: javascript noskimlinks noskimwords">// In Gulpfile 'processors' array
cssnano({
minifyFontWeight: false
})
// In Gruntfile 'processors' array
require('cssnano')({
minifyFontWeight: false
})</pre><p>You can follow the same approach to configure options for a plugin, giving the name of the plugin first then setting its options.</p><p>For example, you can set the precision, (number of decimal places), the calc plugin should use. By default <code class="inline">calc( 100% / 2.76 )</code> would give you <code class="inline">36.23188%</code>. But if you wanted to trim that precision down to two decimal places you could do it like so:</p><pre class="brush: plain noskimlinks noskimwords">// In Gulpfile 'processors' array
cssnano({
calc: {precision: 2}
})
// In Gruntfile 'processors' array
require('cssnano')({
calc: {precision: 2}
})</pre><p>The calc value would now output to <code class="inline">36.23%</code>.</p><p>For more info on cssnano options visit: <a href="http://cssnano.co/options">http://cssnano.co/options</a></p><h2>Quick Recap</h2><p>Let’s have a rundown of what we covered above:</p><ul>
<li>The <a href="https://github.com/postcss/postcss-import">postcss-import</a> plugin gives you an efficient way to inline stylesheets.</li>
<li>It can be used to combine third party stylesheets, including through auto-discovery in your “bower_components” or “npm_modules” folder.</li>
<li>It can be used to allow you to split your stylesheets into parts, then recombine them later.</li>
<li>The <a href="https://github.com/hail2u/node-css-mqpacker">css-mqpacker</a> 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.</li>
<li>The <a href="http://cssnano.co/" rel="external" target="_blank">cssnano</a> pack brings together around 25 different plugins, giving plug and play access to a long list of minification and optimization functions.</li>
<li>It can be configured to use whichever included plugins you want, with the options you want.</li>
</ul><h2>Up Next: Preprocessing with PreCSS</h2><p>In the next tutorial we’ll dive into using PostCSS for preprocessing via an excellent plugin pack named <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">PreCSS</a>. This pack gives immediate access to Sass-like syntax and functionality, with variables, mixins, conditionals, extends and more.</p><p>See you in the next tutorial!</p>2015-10-14T16:29:22.000Z2015-10-14T16:29:22.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24567Using PostCSS for Cross Browser Compatibility<p>In the <a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-exploring-plugins--cms-24566" target="_self">last tutorial</a> we wrapped up our “Quick Start” section of this series, and we’re now ready to move onto using PostCSS to generate stylesheets, employing different kinds of plugins for various purposes.</p><p>In this tutorial we’re going to use PostCSS to create a stylesheet designed for cross browser compatibility. We will:</p><ul>
<li>Have vendor prefixes automatically added in</li>
<li>Add a series of fallbacks for Internet Explorer versions 8, 9 and 10</li>
<li>Add fallbacks for the not yet widely supported <code class="inline">will-change</code> property</li>
</ul><p>Let’s begin!</p><h2>Setup Your Project</h2><p>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.<br></p><p>You can read about how to setup Gulp or Grunt projects for PostCSS in the previous tutorials </p><ul>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" rel="external" target="_blank">PostCSS Quickstart Guide: Gulp Setup</a> or </li>
<li>
<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" rel="external" target="_blank">PostCSS Quickstart Guide: Grunt Setup</a> </li>
</ul><p>respectively.</p><p>If you don't want to manually setup your project from scratch though, you can <a href="https://github.com/tutsplus/using-postcss-for-cross-browser-compatibility/archive/master.zip" target="_self">download the source files attached to this tutorial</a>, and extract either the provided Gulp or Grunt starter project into an empty project folder. <br></p><p>Then, with a terminal or command prompt pointed at the folder, run the command <code class="inline">npm install</code>.</p><h2>Install Plugins</h2><p>Now that you have your empty Gulp or Grunt + PostCSS project ready, we need to install the plugins you’ll be using in this tutorial.</p><p>We’re going to be installing quite a few plugins, so instead of installing them one at a time as we did in the “Quickstart Guides” for Gulp and Grunt, we’ll install them all at once with a single command.</p><p>Whether you’re using Gulp or Grunt, run the following command inside your project folder to install the plugins we’ll be using:</p><pre class="brush: bash noskimlinks noskimwords">npm install autoprefixer postcss-color-rgba-fallback postcss-opacity postcss-pseudoelements postcss-vmin pixrem postcss-will-change --save-dev</pre><p>Now the plugins are installed, let’s go ahead and load them into your project.<br></p><h3>Load Plugins via Gulp</h3><p>If you’re using Gulp, add these variables under the variables already in the file:<br></p><pre class="brush: javascript noskimlinks noskimwords">var autoprefixer = require('autoprefixer');
var color_rgba_fallback = require('postcss-color-rgba-fallback');
var opacity = require('postcss-opacity');
var pseudoelements = require('postcss-pseudoelements');
var vmin = require('postcss-vmin');
var pixrem = require('pixrem');
var will_change = require('postcss-will-change');</pre><p>Now add each of those new variable names into your <code class="inline">processors</code> array:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
will_change,
autoprefixer,
color_rgba_fallback,
opacity,
pseudoelements,
vmin,
pixrem
];</pre><p>Do a quick test that everything is working by running the command <code class="inline">gulp css</code> then checking that a new “style.css” file has appeared in your project's "dest" folder.</p><h3>Load Plugins via Grunt</h3><p>If you’re using Grunt, update the <code class="inline">processors</code> object, which is nested under the <code class="inline">options</code> object, to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('postcss-will-change')(),
require('autoprefixer')(),
require('postcss-color-rgba-fallback')(),
require('postcss-opacity')(),
require('postcss-pseudoelements')(),
require('postcss-vmin')(),
require('pixrem')()
]</pre><p>Do a quick test compile by running the command <code class="inline">grunt postcss</code> then checking that your project’s “dest” folder now contains a new “style.css” file.<br></p><p>You now have all the plugins installed that are required for this tutorial, and you’re ready to move onto seeing how to use them to enhance your stylesheets’ cross browser compatibility.</p><h2>Automatically Add Vendor Prefixing</h2><p>Some of the measures for cross browser compatibility we’ll be covering will only be necessary for specific use cases. Automated vendor prefixing, on the other hand, is something I would suggest should be done with <em>every</em> project, via the <a href="https://github.com/postcss/autoprefixer" rel="external" target="_blank">Autoprefixer</a> plugin created by Andrey Sitnik.</p><p>It can be difficult to keep tabs on which properties require which vendor prefixes at any given time, and by using Autoprefixer you don’t have to. Use Autoprefixer as part of every project and it will check your code against the data from CanIUse.com, then add vendor prefixes as necessary without you having to think about it.</p><p>Let’s do a little test to see Autoprefixer in action. Add the following animation and flexbox code to your project’s “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">@keyframes animationExample {
from {
width: 0;
}
to {
width: 100%;
}
}
.animateThis {
animation: animationExample 2s;
display: flex;
}</pre><p>Run <code class="inline">gulp css</code> or <code class="inline">grunt postcss</code> to compile your file, and your “dest/style.css” should now contain this vendor prefixed code:</p><pre class="brush: css noskimlinks noskimwords">@-webkit-keyframes animationExample {
from {
width: 0;
}
to {
width: 100%;
}
}
@keyframes animationExample {
from {
width: 0;
}
to {
width: 100%;
}
}
.animateThis {
-webkit-animation: animationExample 2s;
animation: animationExample 2s;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}</pre><p>As you can see, vendor prefixes have been automatically added in, as dictated by the data provided from CanIUse.com on <a href="http://caniuse.com/#feat=css-animation" rel="external" target="_blank">animation</a> and <a href="http://caniuse.com/#search=flexbox" rel="external" target="_blank">flexbox</a>.</p><h3>Specifying Browser Support Levels<br>
</h3><p>Autoprefixer uses <a href="https://github.com/ai/browserslist" rel="external" target="_blank">Browserlist</a> to determine which browser versions it will add support for. Under default settings it will apply vendor prefixes as required for:</p><ul>
<li>
<strong>&gt; 1%:</strong> browsers used by more than one percent of people globally</li>
<li>
<strong>last 2 versions:</strong> the last two versions of every browser tracked by CanIUse.com</li>
<li>
<strong>Firefox ESR:</strong> the latest Firefox version</li>
<li>
<strong>Opera 12.1:</strong> Opera version 12.1</li>
</ul><p>The example we ran through above was compiled under Autoprefixer’s default settings. This meant support for IE10 and Safari 8 was included, so the <code class="inline">-ms-</code> and <code class="inline">-webkit-</code> prefixes they require for <code class="inline">animation</code> and <code class="inline">flexbox</code> were automatically inserted.</p><p>However, IE11 and Safari 9 don’t require these prefixes, so if you were to set your browserlist configuration to support only IE11+ and Safari 9+ these prefixes would no longer be added.</p><p>Try this out by passing a <code class="inline">browsers</code> setting through to Autoprefixer in your Gulpfile or Gruntfile like so: </p><pre class="brush: javascript noskimlinks noskimwords">// In the Gulpfile 'processors' array:
autoprefixer({browsers:'safari &gt;= 9, ie &gt;= 11'}),
// In the Gruntfile 'processors' array:
require('autoprefixer')({ browsers: ['safari &gt;= 9, ie &gt;= 11'] }),</pre><p>Now if you recompile your CSS you’ll see there is no difference between your original and compiled code. This is because, with no support requested for Safari 8 or IE10, no vendor prefixes have been added in to suit them.</p><h4>Related Links:</h4><ul>
<li>Autoprefixer: <a href="https://github.com/postcss/autoprefixer">https://github.com/postcss/autoprefixer</a>
</li>
<li>Browserlist: <a href="https://github.com/ai/browserslist">https://github.com/ai/browserslist</a>
</li>
</ul><h2>Add Fallback for “will-change” Property</h2><p>The <code class="inline">will-change</code> property is used to let a browser know ahead of time that certain elements of your design are going to be animated. This allows the browser to optimize the rendering process and prevent delays and flickers. However, at present this property is not supported by IE / Edge, Safari or Opera Mini.</p><p>The <a href="https://github.com/postcss/postcss-will-change" rel="external" target="_blank">postcss-will-change</a> plugin, also created by Andrey Sitnik, adds a fallback that will help these browsers do a better job of rendering, even if not with the efficiency they could if they supported <code class="inline">will-change</code>. It does so by adding the <code class="inline">backface-visibility</code> property, which triggers the creation of a compositor layer that will be handled by the GPU.</p><p>For example, add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.thisWillChange {
will-change: transform;
}</pre><p>Compile your stylesheet and you should see the fallback appear in your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.thisWillChange {
backface-visibility: hidden;
will-change: transform;
}</pre><p><strong>Note</strong>: this plugin should be loaded <em>before</em> Autoprefixer in your Gulpfile/Gruntfile. This is to allow Autoprefixer to add vendor prefixes to the <code class="inline">backface-visibility</code> property, like so:</p><pre class="brush: css noskimlinks noskimwords">/* Fallback with vendor prefixes */
.thisWillChange {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
will-change: transform;
}</pre><h4>Related Links</h4><ul>
<li>postcss-will-change plugin: <a href="https://github.com/postcss/postcss-will-change">https://github.com/postcss/postcss-will-change</a>
</li>
<li><a href="https://dev.opera.com/articles/css-will-change-property/" rel="external" target="_blank">Everything You Need to Know About the CSS will-change Property</a></li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=will-change">http://caniuse.com/#feat=will-change</a>
</li>
</ul><h2>Add Fallbacks for Old IE Issues</h2><p>Thanks to improved browser versions from Microsoft, and major groups leading the way in dropping support for old IE, we’re gradually edging closer to not having to constantly consider fallbacks and workarounds for problematic legacy browsers. Microsoft itself will be dropping support for IE8 in <a href="http://www.zdnet.com/article/microsoft-to-drop-support-for-older-versions-of-internet-explorer/" rel="external" target="_blank">2016</a>. <a href="http://webdesign.tutsplus.com/articles/new-features-in-bootstrap-4-alpha--cms-24730" target="_self">Bootstrap 4 alpha</a> was recently released and it has also <a href="http://blog.getbootstrap.com/2015/08/19/bootstrap-4-alpha/" rel="external" target="_blank">dropped support for IE8</a>. Google stopped supporting IE8 in <a href="http://googleappsupdates.blogspot.co.uk/2012/09/supporting-modern-browsers-internet.html" rel="external" target="_blank">2012</a> and dropped IE9 support in <a href="http://googleappsupdates.blogspot.com.au/2013/11/end-of-support-for-internet-explorer-9.html" rel="external" target="_blank">2013</a>.</p><p>All that said, at the end of the day every project has to be assessed on a case by case basis, and if you’re targeting a demographic that has high usage rates of legacy browsers, you may have no choice but to do your best to support them. If that’s the case, the following plugins can help you make that process a little less painful.</p><h3>Create <code class="inline">rgba()</code> Color Fallbacks</h3><p>IE8 has no support for <code class="inline">rgba()</code> colors, so the <a href="https://github.com/postcss/postcss-color-rgba-fallback">postcss-color-rgba-fallback</a> plugin by Guillaume Demesy adds a flat hexadecimal color as a fallback. </p><p>For example, add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.rgbaFallback {
background: rgba(0,0,0,0.5);
}</pre><p>Compile and you should see the hexcode fall back added to your “dest/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.rgbaFallback {
background: #000000;
background: rgba(0,0,0,0.5);
}</pre><h4>Related Links</h4><ul>
<li>postcss-color-rgba-fallback plugin: <a href="https://github.com/postcss/postcss-color-rgba-fallback">https://github.com/postcss/postcss-color-rgba-fallback</a>
</li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=css3-colors">http://caniuse.com/#feat=css3-colors</a>
</li>
</ul><h3>Create <code class="inline">opacity</code> Fallbacks</h3><p>IE8 can’t handle the <code class="inline">opacity</code> property, so the <a href="https://github.com/iamvdo/postcss-opacity">postcss-opacity</a> plugin by Vincent De Oliveira adds an IE specific filter to achieve the same effect.</p><p>Add this code to your source stylesheet:</p><pre class="brush: css noskimlinks noskimwords">.opacityFallback {
opacity: 0.5;
}</pre><p>After compilation you should see the appropriate <code class="inline">-ms-filter</code> fallback added:</p><pre class="brush: css noskimlinks noskimwords">.opacityFallback {
opacity: 0.5;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
}</pre><h4>Related Links</h4><ul>
<li>postcss-opacity plugin: <a href="https://github.com/iamvdo/postcss-opacity">https://github.com/iamvdo/postcss-opacity</a>
</li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=css-opacity">http://caniuse.com/#feat=css-opacity</a>
</li>
</ul><h3> Convert <code class="inline">::</code> into <code class="inline">:</code> on Pseudo-elements</h3><p>It’s considered <a href="http://www.w3.org/TR/selectors/#pseudo-elements" rel="external" target="_blank">best practice</a> when generating pseudo-<em>elements</em> such as <code class="inline">.element::before</code> to use a double colon notation <code class="inline">::</code>. This is to help distinguish them from pseudo-<em>classes</em> such as <code class="inline">.element:hover</code> which should use a single colon notation <code class="inline">:</code>.</p><p>However, IE8 doesn’t support the double colon notation <code class="inline">::</code> to create pseudo-elements, it only supports a single colon <code class="inline">:</code>. By using the <a href="https://github.com/axa-ch/postcss-pseudoelements" rel="external" target="_blank">postcss-pseudoelements</a> plugin by Sven Tschui you can code according to best practices, and have the notation changed automatically.<br></p><p>Add the following double <code class="inline">::</code> notation code:</p><pre class="brush: css noskimlinks noskimwords">.pseudo-element::before {
content: '';
}</pre><p>Compile your file and you should see it has been reduced to the single <code class="inline">:</code> notation:</p><pre class="brush: css noskimlinks noskimwords">.pseudo-element:before {
content: '';
}</pre><p>By coding to best practices and using this plugin, once IE8 is completely retired you can just reprocess your CSS without the plugin and have proper syntax in place.</p><h4>Related Links</h4><ul>
<li>postcss-pseudoelements plugin: <a href="https://github.com/axa-ch/postcss-pseudoelements">https://github.com/axa-ch/postcss-pseudoelements</a>
</li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=css-gencontent">http://caniuse.com/#feat=css-gencontent</a>
</li>
</ul><h3>Add <code class="inline">vm</code> Fallback for <code class="inline">vmin</code>
</h3><p>In IE9 the viewport relative unit <code class="inline">vmin</code> is not supported, but instead uses the equivalent unit <code class="inline">vm</code>. If you’re catering to IE9, the <a href="https://github.com/iamvdo/postcss-vmin" rel="external" target="_blank">postcss-vmin</a> plugin by Vincent De Oliveira will add <code class="inline">vm</code> units as a fallback.</p><p>Add this code to your “src/style.css” file:</p><pre class="brush: css noskimlinks noskimwords">.vmFallback {
width: 50vmin;
}</pre><p>Recompile, and the resulting code should have the <code class="inline">vm</code> unit fallback added in:</p><pre class="brush: css noskimlinks noskimwords">.vmFallback {
width: 50vm;
width: 50vmin;
}</pre><h4>Related Links</h4><ul>
<li>postcss-vmin plugin: <a href="https://github.com/iamvdo/postcss-vmin">https://github.com/iamvdo/postcss-vmin</a>
</li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=viewport-units">http://caniuse.com/#feat=viewport-units</a>
</li>
</ul><h3>Add <code class="inline">px</code> Fallback for <code class="inline">rem</code> Units</h3><p>IE8 doesn’t support <code class="inline">rem</code> units at all, and in both IE9 and IE10 they are unsupported in <code class="inline">psuedo-elements</code> and <code class="inline">font</code> shorthand declaration. With the <a href="https://github.com/robwierzbowski/node-pixrem" rel="external" target="_blank">node-pixrem</a> plugin by Vincent De Oliveira and Rob Wierzbowski you can have <code class="inline">px</code> based fallbacks added automatically wherever you use <code class="inline">rem</code> units.</p><p>Add this code to your source stylesheet:<br></p><pre class="brush: css noskimlinks noskimwords">.remFallback {
height: 10rem;
font: 2rem Arial;
}
.remFallback::before {
content: '';
line-height: 1rem;
}</pre><p>Recompile and you should see all the appropriate <code class="inline">px</code> fallbacks added:</p><pre class="brush: css noskimlinks noskimwords">.remFallback {
height: 160px;
height: 10rem;
font: 32px Arial;
font: 2rem Arial;
}
.remFallback:before {
content: '';
line-height: 16px;
line-height: 1rem;
}</pre><h4>Related Links</h4><ul>
<li>node-pixrem plugin: <a href="https://github.com/robwierzbowski/node-pixrem">https://github.com/robwierzbowski/node-pixrem</a>
</li>
<li>CanIUse info: <a href="http://caniuse.com/#feat=rem">http://caniuse.com/#feat=rem</a>
</li>
</ul><h2>Let’s Recap</h2><p>To sum up what we’ve covered in the above:</p><ul>
<li>Autoprefixer is an must-use tool for every project</li>
<li>Autoprefixer can be configured to add vendor prefixes based on whatever browsers you need to support</li>
<li>If using animation in your project, consider using the plugin <a href="https://github.com/postcss/postcss-will-change" rel="external" target="_blank">postcss-will-change</a>
</li>
<li>If supporting IE8, consider using the plugins <a href="https://github.com/postcss/postcss-color-rgba-fallback">postcss-color-rgba-fallback</a>, <a href="https://github.com/iamvdo/postcss-opacity">postcss-opacity</a>, <a href="https://github.com/axa-ch/postcss-pseudoelements" rel="external" target="_blank">postcss-pseudoelements</a> and <a href="https://github.com/iamvdo/postcss-vmin" rel="external" target="_blank">postcss-vmin</a>.</li>
<li>If supporting IE8, IE9, IE10 consider using the <a href="https://github.com/robwierzbowski/node-pixrem" rel="external" target="_blank">node-pixrem</a> plugin</li>
</ul><h2>In the Next Tutorial</h2><p>Coming up next in our PostCSS Deep Dive series is a tutorial on how to use plugins to minify and optimize your CSS. We’ll cover inlining <code class="inline">@import</code> files, combining media queries, stripping white space and several more methods to make your stylesheets as streamlined as possible. See you there!</p>2015-10-13T15:00:20.000Z2015-10-13T15:00:20.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24566PostCSS Quickstart Guide: Exploring Plugins<p>As you will have gathered from the previous entries in this series, PostCSS is all about the plugins. The plugins you choose will completely define your experience with PostCSS. </p><p>Given that they are so integral and fundamental, before we move on to actually producing stylesheets via PostCSS, we’re going to take a look at how you can explore the PostCSS plugin ecosystem. Through this you’ll also get a view into how powerful PostCSS is, and how it offers functionality that can’t be equally created through any other existing means.</p><p>We’ll cover where you can go to keep tabs on the latest and greatest plugins, the categories these plugins typically fall into, and considerations for how to load all these plugins into projects in a logical way.</p><h2>Finding Plugins</h2><p>As you start getting into working with PostCSS there are three locations you’ll want to keep an eye on for finding great plugins.</p><h3>PostCSS Github Page</h3><p>The main page of <a href="https://github.com/postcss/postcss#plugins" target="_self">the PostCSS Github repo</a> currently maintains a comprehensive categorized list of plugins. This list does tend to get updated frequently so it’s quite a reliable place to go and see what plugins are available for different aspects of development.</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/30/posts/24566/image/gh.png"><figcaption><a href="https://github.com/postcss/postcss#plugins">https://github.com/postcss/postcss#plugins</a></figcaption></figure><h3>Catalog Site postcss.parts</h3><p>A relatively new, and very welcome, addition to the PostCSS world is the site <a href="http://postcss.parts/" rel="external" target="_blank">postcss.parts</a>, which provides a searchable catalog of PostCSS plugins.</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/30/posts/24566/image/postcss.png"><figcaption><a href="http://postcss.parts/">http://postcss.parts</a></figcaption></figure><h3>@postcss Twitter</h3><p>Right now PostCSS is seeing a new and interesting plugins being released on a regular basis. The above two locations don't highlight new plugins so at a glance you won't know if there are items you haven't seen before. For that reason, it's a great idea to follow or frequently visit <a href="http://postcss.parts/" rel="external" target="_blank">@PostCSS</a> on Twitter.</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/30/posts/24566/image/tw.jpg"><figcaption><a href="https://twitter.com/postcss">https://twitter.com/postcss</a></figcaption></figure><h2>Types of Plugins</h2><p>The breadth of functionality in plugins that can work with PostCSS is huge, so it’s a great idea to have an introduction to the general <em>types</em> of plugins you’re likely to encounter before you move into trialling any of them.</p><h3><a href="https://github.com/postcss/postcss#packs" rel="external" target="_blank">Packs</a></h3><p>The fundamental nature of PostCSS is that it provides modular CSS processing. As such, individual plugins are encouraged to only cover a small, tightly defined set of functionality. Megalithic multifunction plugins that do everything at once are discouraged.</p><p>That said, sometimes you do want to incorporate a long list of functionality into a project, and you’d rather not have to individually install and configure twenty different plugins. This is where “packs” come into play. Packs bring together several modular plugins under a thematic umbrella, allowing them all to be installed and deployed at once.</p><p>For example, the <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">PreCSS</a> pack combines nine separate PostCSS plugins to create Sass-like functionality. The <a href="https://github.com/ben-eb/cssnano" rel="external" target="_blank">cssnano</a> pack uses around twenty PostCSS plugins to provide CSS minification and optimization. By using these packs you save yourself having to install and load each of the plugins manually.</p><h3><a href="https://github.com/postcss/postcss#future-css-syntax" rel="external" target="_blank">Future CSS Syntax</a></h3><p>Future CSS is all about letting you write syntax we know is coming up in the W3C spec, but might not be fully supported in browsers yet.</p><p>For example, you might want to be able to use the upcoming <a href="https://drafts.csswg.org/css-color/#hex-notation" rel="external" target="_blank">eight or four digit hexidecimal notation</a> to create opaque colors. To generate a slightly transparent blue you could use a color code like <code class="inline">#0000ffcc</code>, or its abbreviated form <code class="inline">#00fc</code>, and run the <a href="https://github.com/postcss/postcss-color-hex-alpha">postcss-color-hex-alpha</a> plugin to convert that into the widely supported format <code class="inline">rgba(0, 0, 100%, 0.8)</code>.<br></p><p>The most prominent presence in PostCSS future CSS is the <a href="http://cssnext.io/" rel="external" target="_blank">cssnext</a> pack, which brings a great deal of spec compliant future CSS to the table. However, at present its developer Maxime Therouin is taking the pack through a major transition in how it functions. As such, we’ll hold fire on bringing you a future CSS tutorial until the transition is complete.</p><h3><a href="https://github.com/postcss/postcss#fallbacks" rel="external" target="_blank">Fallbacks</a></h3><p>Where future CSS is about making tomorrow’s code work in today’s browsers, fallbacks are essentially about making today’s code work in yesterday’s browsers. In a perfect world we’d never have to think about old and outdated browsers, but the reality is that there are still some projects for which supporting legacy browsers is essential. The fallbacks category of PostCSS plugins can help out where that’s the case.</p><p>All of these plugins run hands-free, by which I mean you write your code according to current standards, and the plugins will find code that needs legacy fallbacks and automatically insert them as required.</p><p>For example, you can have flat colors added in as fallbacks for <code class="inline">rgba()</code> colors by the <a href="https://github.com/postcss/postcss-color-rgba-fallback" rel="external" target="_blank">postcss-color-rgba</a> plugin, or add IE8 compatible fallbacks for <code class="inline">opacity</code> via the <a href="https://github.com/iamvdo/postcss-opacity" rel="external" target="_blank">postcss-opacity</a> plugin. The most well known of these plugins is <a href="https://github.com/postcss/autoprefixer" rel="external" target="_blank">Autoprefixer</a>, which adds vendor prefixes as required, based on data from CanIUse.com.</p><p>You’ll learn more about fallback plugins in the upcoming “For Cross Browser Compatibility” tutorial in this series.</p><h3><a href="https://github.com/postcss/postcss#language-extensions" rel="external" target="_blank">Language Extensions</a></h3><p>Language extension plugins add functionality to CSS that would otherwise not be there. By comparison, you might consider most preprocessors to be entirely comprised of language extensions. In fact, users of Sass, Stylus and LESS will likely feel quite at home with many PostCSS language extensions, such as those adding mixins, variables, conditionals, loops, nesting, extending and so forth.</p><p>Because PostCSS is completely flexible however, there are also language extensions offering functionality not commonly found in preprocessors. For example, the <a href="https://github.com/ileri/postcss-bem" rel="external" target="_blank">postcss-bem</a> plugin adds syntax specifically for creating CSS that follows the BEM / SUIT methodology, (more on that in a later tutorial). The <a href="https://github.com/daleeidd/postcss-define-property" rel="external" target="_blank">postcss-define-property</a> plugin allows you to create your own custom properties, or redefine native properties. And the <a href="https://github.com/rtsao/postcss-match" rel="external" target="_blank">postcss-match</a> plugin allows you to use not only conditionals, but pattern-matching logic in your code.</p><p>With this variety all indications are that PostCSS will mature to the point where it can provide much of the functionality many of us look for in preprocessors, but also considerable functionality beyond that.</p><h3><a href="https://github.com/postcss/postcss#colors" rel="external" target="_blank">Colors</a></h3><p>Many of the color plugins currently available for PostCSS deal with transforming colors from one format into another, for example from <code class="inline">#hex.a</code> to <code class="inline">rgba()</code>, <code class="inline">hcl(H,C,L)</code> to <code class="inline">#rgb</code>, or pantone to <code class="inline">#rgb</code>. As well as that, some of the most useful plugins handle color manipulation, such as mixing two colors, or scaling the lightness or darkness of them.</p><p>One particular favorite of mine allows you to take your existing color scheme, then output a version as it would appear to people with specific forms of color blindness. There’s nothing like experiencing something first hand to help you gauge how accessible your designs are.</p><p>We’ll go into more detail on color plugins in our later preprocessing, shorthand, and “miscellaneous goodies” tutorials.</p><h3><a href="https://github.com/postcss/postcss#images-and-fonts" rel="external" target="_blank">Images and Fonts</a></h3><p>This category of plugins handles a lot of optimization tasks, such as packing Base64 data, generating CSS sprite sheets and SVG optimization. You’ll also find several other types of image and font tools, such as automatic SVG to PNG conversion for IE8, automatic WebP image generation and inclusion for supporting browsers, <code class="inline">@font-face</code> shortcuts, retina support shortcuts and more.</p><h3><a href="https://github.com/postcss/postcss#grids" rel="external" target="_blank">Grids</a></h3><p>Discovering that grid systems could be written in PostCSS, without needing to load prewritten stylesheets or use preprocessor mixins, was the first thing that really opened my eyes as to how powerful PostCSS is. I had previously thought PostCSS was primarily about filtering and modifying existing CSS, however grid systems show that it can be used to create entire libraries of external styles.</p><p>There are currently three grid systems available for PostCSS:</p><ul>
<li>
<a href="https://github.com/corysimmons/lost" rel="external" target="_blank">Lost</a>, created by Cory Simmons</li>
<li>
<a href="https://github.com/andyjansson/postcss-grid" rel="external" target="_blank">postcss-grid</a>, created by Andy Jansson</li>
<li>
<a href="https://github.com/jo-asakura/postcss-neat" rel="external" target="_blank">postcss-neat</a>, created by Jo Asakura</li>
</ul><h3><a href="https://github.com/postcss/postcss#optimizations" rel="external" target="_blank">Optimizations</a></h3><p>PostCSS optimization plugins fall into two general categories: minification and code modification. Through these plugins you can perform minification tasks like stripping whitespace and comments, and you can also have more complex modifications done like combining matching media queries, inlining <code class="inline">@import</code> stylesheets, optimizing font weights, removing empty or duplicate rules and so on.</p><p>We’ll cover more on this category of PostCSS plugins in the upcoming “For Minification and Optimization” tutorial.</p><h3><a href="https://github.com/postcss/postcss#shortcuts" rel="external" target="_blank">Shortcuts</a></h3><p>As a preprocessor user, I always found one of the biggest benefits was the ability to cut down on the amount of code I had to write through using variables and mixins. Through PostCSS I have discovered even more extensive means to make code writing more efficient via the long list of shortcut and shorthand plugins available.</p><p>You can choose to use shorthand for properties, either defining your own or using existing shorthand, for example <code class="inline">w</code> instead of <code class="inline">width</code>, <code class="inline">h</code> instead of <code class="inline">height</code> and so on. You can output <code class="inline">@font-face</code> code, <code class="inline">transform</code> code, triangles and circles all in one line each. And you can shortcut all kinds of common tasks including link styling, centering, clearfixing, positioning, sizing, spacing and outputting color codes.</p><p>We’ll go into these plugins in more depth in the “Shortcuts and Shorthand” tutorial.</p><h3>
<a href="https://github.com/postcss/postcss#analysis" rel="external" target="_blank">Analysis</a> &amp; <a href="https://github.com/postcss/postcss#reporters" rel="external" target="_blank">Reporters</a>
</h3><p>PostCSS can also be used for more than transforming CSS, it can also be used to provide feedback as you develop your CSS. Some of the analysis and reporting plugins available include a linter for BEM/SUIT code, a plugin to give you a breakdown of your code via CSSstats, “DoIUse” to let you know how your code lines up with data from Can I Use, and a Modernizr file generator.</p><h3><a href="https://github.com/postcss/postcss#others" rel="external" target="_blank">Others</a></h3><p>There are some great PostCSS plugins that don’t quite fit into a specific category but are far too good to pass over. For example, we have <a href="https://github.com/morishitter/postcss-style-guide" rel="external" target="_blank">postcss-style-guide</a> which automatically generates a style guide based on your CSS. There’s also the <a href="https://github.com/MohammadYounes/rtlcss" rel="external" target="_blank">rtlcss</a> plugin, used by WordPress, which generates a right to left version of your stylesheet.</p><p>We’ll cover some of these great plugins in the tutorial “Miscellaneous Goodies”.</p><h3><a href="https://github.com/postcss/postcss#fun" rel="external" target="_blank">Fun</a></h3><p>The “fun” category includes such gems as <a href="https://github.com/HashanP/postcss-spiffing" rel="external" target="_blank">postcss-spiffing</a> which allows you to use UK spelling, for example <code class="inline">colour</code> instead of <code class="inline">color</code>, and well mannered syntax such as <code class="inline">!please</code> instead of <code class="inline">!important</code>.</p><p>You’re unlikely to see any of this category’s plugins used in a real project, however a genuine benefit they offer is to act as easily understandable examples for aspiring plugin developers. Being quite simple and brief, they’re perfect for taking a look inside and seeing the essentials of how PostCSS plugins are made.</p><h2>Plugin Execution Sequence</h2><p>One of the main considerations you have to make when loading up the array of PostCSS plugins is the order in which you run them. You’ll have to pause and think through your list, determining if one plugin might need to run after another in order to do what you want it to.</p><p>For example, you might use a plugin like <a href="https://github.com/postcss/postcss-simple-vars" rel="external" target="_blank">postcss-simple-vars</a> that adds support for variables, and you might use it to store an <code class="inline">rgba()</code> value like so:</p><pre class="brush: css noskimlinks noskimwords">/* source code */
$color: rgba( 0, 0, 0, 0.5);
.style {
background: $color;
}
/* compiles to: */
.style {
background: rgba( 0, 0, 0, 0.5);
}</pre><p>You might also want to use a plugin like <a href="https://github.com/postcss/postcss-color-rgba-fallback">postcss-color-rgba-fallback</a> to add a flat hexcode as a fallback, giving you:</p><pre class="brush: css noskimlinks noskimwords">/* compiles to: */
.style {
background: #000;
background: rgba( 0, 0, 0, 0.5);
}</pre><p>In this case you would have to make sure you ran the variables plugin <em>before</em> the fallback plugin. </p><p>If you ran the fallback plugin first it would just find <code class="inline">background: $color;</code> in your CSS and not know there was an <code class="inline">rgba()</code> value for it to work with.</p><p>However, by running the variables plugin first, when the fallback plugin runs it will find <code class="inline">background: rgba( 0, 0, 0, 0.5);</code> and go ahead and add in the required fallback.</p><p>The load order for plugins is something that will change with each set of plugins, so you may find you just need to do a little experimentation sometimes to get everything working together nicely.</p><h2>Let’s Recap</h2><p>To sum up exploring PostCSS plugins:</p><ul>
<li>Find plugins at the <a href="https://github.com/postcss/postcss#plugins" rel="external" target="_blank">PostCSS Github repo</a> and <a href="http://postcss.parts/" rel="external" target="_blank">postcss.parts</a>
</li>
<li>Stay tuned to <a href="http://postcss.parts/" rel="external" target="_blank">@PostCSS</a> to learn about new plugins</li>
<li>Plugin packs allow you to install several similarly themed plugins at once</li>
<li>PostCSS plugins fall into many, considerably different categories</li>
<li>When loading your selection of plugins, be sure to consider their execution sequence</li>
</ul><h2>In the Next Tutorial</h2><p>We’ve completed our “Quick Start” guide to PostCSS and we’re ready to jump into the practical and start producing some actual CSS code.</p><p>In the next tutorial we’ll start with how to use PostCSS to generate cross-browser compatible code by way of automated insertion of vendor prefixes, and a number of fallbacks for properties with legacy browsers, in particular IE8.</p><p>See you in the next tutorial!</p>2015-10-07T12:43:20.000Z2015-10-07T12:43:20.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24545PostCSS Quickstart Guide: Grunt Setup<p>In the <a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-gulp-setup--cms-24543" target="_self">last tutorial</a> we went through how to setup a PostCSS project with Gulp. In this tutorial we’ll achieve the same ends, by using <a href="http://gruntjs.com/" rel="external" target="_blank">Grunt</a>. By the end of this tutorial you’ll know how to setup a PostCSS + Grunt project with any selection of plugins you choose.</p><p><strong>Note</strong>: If you’ve never worked with command line or task runners before, I recommend that before you begin this tutorial you check out our free series: <a href="http://webdesign.tutsplus.com/series/the-command-line-for-web-design--cms-777" rel="external" target="_blank">The Command Line for Web Design</a>.<br></p><h3>Prerequisites</h3><p>As we’ll be working with Grunt, we’ll assume you already have the prerequisites for its use installed:</p><ul>
<li>Node.js</li>
<li>NPM</li>
<li>Git</li>
</ul><p>If you’re not sure if you have these installed, please follow the tutorial <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-taming-3rd-party-packages--cms-23451" rel="external" target="_blank">The Command Line for Web Design: Taming 3rd Party Packages</a>.</p><p>Please ensure you have Grunt CLI installed globally and understand its basic use by following <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-automation-with-grunt--cms-23454" rel="external" target="_blank">The Command Line for Web Design: Automation with Grunt</a>. Additionally, follow the instructions in the tutorial’s “Setup Project for Grunt” section. Before you move on you should have a project folder with:</p><ul>
<li>A “gruntfile.js” (Gruntfile)</li>
<li>A “package.json” file</li>
<li>Grunt installed into the “node_modules” folder and set as a dev dependency for your project.</li>
</ul><h2>PostCSS via Grunt</h2><p>Into your project folder add two subfolders, one named “src” and the other named “dest”. The “src” folder will hold your unprocessed CSS files, and PostCSS will write your compiled CSS files into the “dest” folder.<br></p><p>The next thing you’ll need to do is install the Grunt plugin for PostCSS into your project: we’ll be using <a href="https://github.com/nDmitry/grunt-postcss" rel="external" target="_blank">grunt-postcss</a> to handle compilation.</p><p>In a terminal/command prompt pointed at your project folder, run the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install grunt-postcss --save-dev</pre><p>At this point your project structure should look like this:</p><figure class="post_image"><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24545/image/gruntpostcssfolders.png"></figure><p>Open up your Gruntfile for editing and start by adding the basic shell of code that all Gruntfiles require:</p><pre class="brush: javascript noskimlinks noskimwords">module.exports = function(grunt) {
};</pre><p>Inside that, we’re going to use the <code class="inline">grunt.loadNpmTasks()</code> function to load in our <code class="inline">grunt-postcss</code> plugin like so:</p><pre class="brush: javascript noskimlinks noskimwords">module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-postcss');
};</pre><p>Now we’re ready to start configuring the Grunt task we’ll use to run postcss. First, add the <code class="inline">grunt.initConfig()</code> function above the line we just added:</p><pre class="brush: javascript noskimlinks noskimwords">module.exports = function(grunt) {
grunt.initConfig({
});
grunt.loadNpmTasks('grunt-postcss');
};</pre><p>Inside that, setup an object named <code class="inline">postcss</code> like so:</p><pre class="brush: plain noskimlinks noskimwords">module.exports = function(grunt) {
grunt.initConfig({
postcss: {
}
});
grunt.loadNpmTasks('grunt-postcss');
};</pre><p>Inside the new <code class="inline">postcss</code> object we’ll add two more nested objects, one named <code class="inline">options</code> and one named <code class="inline">dist</code>:</p><pre class="brush: javascript noskimlinks noskimwords">module.exports = function(grunt) {
grunt.initConfig({
postcss: {
options: {
},
dist: {
}
}
});
grunt.loadNpmTasks('grunt-postcss');
};</pre><p>The <code class="inline">options</code> object will hold the configuration for PostCSS, and the <code class="inline">dist</code> object will hold information on where our CSS files should be read <em>from</em> and written <em>to</em>.</p><p>Go ahead now and create a CSS file named “style.css” in your project’s “src” folder. Add some test code to it, such as:</p><pre class="brush: css noskimlinks noskimwords">.test {
background: black;
}</pre><p>Now update the <code class="inline">dist</code> object to specify “src/style.css” as our source file, and “dest/style.css” as the file we want to generate:</p><pre class="brush: javascript noskimlinks noskimwords"> dist: {
src: 'src/style.css',
dest: 'dest/style.css'
}</pre><p>Then, inside the <code class="inline">options</code> object, add an empty array named <code class="inline">processors</code>. This is where we’ll configure PostCSS plugins for use a little later. For now, just update it to:</p><pre class="brush: javascript noskimlinks noskimwords"> options: {
processors: [
]
},</pre><h3>Run a Test Compile</h3><p>Your basic <code class="inline">postcss</code> task is now ready to go. To test it out, with your terminal/command prompt still pointed at your project folder, run the command:</p><pre class="brush: bash noskimlinks noskimwords">grunt postcss</pre><p>In your terminal you should see this message:</p><pre class="brush: bash noskimlinks noskimwords">Running "postcss:dist" (postcss) task
&gt;&gt; 1 processed stylesheet created.</pre><p>And now in your “dest” folder you should find a new “style.css” file, containing the same code as the “style.css” file in your “src” folder.</p><h2>Add PostCSS Plugins</h2><p>Next we’ll add a selection of PostCSS plugins and packs: <a href="https://github.com/postcss/autoprefixer" rel="external" target="_blank">Autoprefixer</a> (adds vendor prefix), <a href="http://cssnext.io/setup/" rel="external" target="_blank">cssnext</a> (enables future syntax) and <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">precss</a> (extends with Sass like functionality).</p><p>Run the following commands to install each one into your project:</p><pre class="brush: bash noskimlinks noskimwords">npm install autoprefixer --save-dev
npm install cssnext --save-dev
npm install precss --save-dev</pre><p><strong>Note</strong>: The <code class="inline">cssnext</code> and <code class="inline">precss</code> installations may take a little while as they are packs of multiple plugins.</p><p>Now we’re ready to load each of the plugins via the <code class="inline">processors</code> array we created earlier. Update that array to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('autoprefixer')(),
require('cssnext')(),
require('precss')()
]</pre><p>Let’s go ahead now add some test code to our source “style.css” file and check that our newly setup PostCSS plugins are working as expected. </p><p>Delete what you already have in the file and add this CSS instead:</p><pre class="brush: css noskimlinks noskimwords">/* Testing autoprefixer */
.autoprefixer {
display: flex;
}
/* Testing cssnext */
.cssnext {
background: color(red alpha(-10%));
}
/* Testing precss */
.precss {
@if 3 &lt; 5 {
background: green;
}
@else {
background: blue;
}
}</pre><p>Run the <code class="inline">grunt postcss</code> command again now, and the resulting file in your “dest” folder should have the following content:</p><pre class="brush: css noskimlinks noskimwords">/* Testing autoprefixer */
.autoprefixer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
/* Testing cssnext */
.cssnext {
background: rgba(255, 0, 0, 0.9);
}
/* Testing precss */
.precss {
background: green
}</pre><p>You’ll see in the <code class="inline">.autoprefixer</code> class, vendor prefixes have been added by Autoprefixer. In the <code class="inline">.cssnext</code> class, an <code class="inline">rgba()</code> color has been generated by cssnext. And finally in the <code class="inline">.precss</code> class, the <code class="inline">@if @else</code> conditional has been evaluated by PreCSS.</p><h3>Setting Plugin Options</h3><p>Note, if you want configure options for a plugin, pass your options through the second pair of brackets after the <code class="inline">require()</code> function for that plugin. For example, you might specify the browser list you want Autoprefixer to work off, like so:</p><pre class="brush: javascript noskimlinks noskimwords"> processors: [
require('autoprefixer')({browsers: ['last 1 version']}),
require('cssnext')(),
require('precss')()
]</pre><h2>Sharing Your Project</h2><p>The beauty of PostCSS is in its ability to be configured with any combination of plugins. The challenge this brings forward, however, is ensuring that other people who wish to work on a project have the same setup of PostCSS plugins. Thanks to <a href="https://www.npmjs.org/" rel="external" target="_blank">npm</a>, this challenge is handled through its system of dependency management.</p><p>Because you are using the <code class="inline">--save-dev</code> flag every time you install a plugin into your project, it will be added to your “project.json” file as a dev dependency. This means if you want to share your project with others, they can run the command <code class="inline">npm install</code> on the package you share with them and have all the same plugins automatically installed.<br></p><p>To learn more about how dependency management works with NPM check out the tutorial <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-taming-3rd-party-packages--cms-23451" rel="external" target="_blank">The Command Line for Web Design: Taming 3rd Party Packages</a>.</p><h2>Let’s Recap</h2><p>In summary of everything covered above:</p><ul>
<li>Create an npm project with Grunt installed and a Gruntfile inside</li>
<li>Install the grunt-postcss plugin</li>
<li>Setup your Gruntfile shell, loading grunt-postcss with <code class="inline">grunt.loadNpmTasks('grunt-postcss');</code>
</li>
<li>Create a grunt task to compile your CSS</li>
<li>Within the task, setup an <code class="inline">options</code> object containing a <code class="inline">processors</code> array</li>
<li>Also within the task, setup a <code class="inline">dist</code> object specifying your source files and the destination for compiled files</li>
</ul><p>From there, you can follow the same essential steps to enable any PostCSS plugin in your project:</p><ul>
<li>Install the plugin into your project with <br><code class="inline">npm install &lt;plugin_name&gt; --save-dev</code>
</li>
<li>Add that variable name into your <code class="inline">preprocessors</code> array using the require() function <br><code class="inline">require('&lt;plugin_name&gt;')()</code>.</li>
</ul><p>Check out <a href="https://github.com/tutsplus/postcss-quickstart-guide-grunt-setup" target="_self">the Github repo</a> for starter files and completed examples.<br></p><h2>Up Next: Exploring Plugins</h2><p>Now you know how to use either Gulp or Grunt to use PostCSS with any plugins you choose. The next thing you need is a way explore the PostCSS plugin ecosystem and find great plugins that are perfect for the kind of projects you want to create.</p><p>We’ll go through exactly how you can do that in the next tutorial; “<a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-exploring-plugins--cms-24566" target="_self">Quickstart Guide: Exploring Plugins</a>”.</p>2015-10-05T12:13:19.000Z2015-10-05T12:13:19.000ZKezz Braceytag:webdesign.tutsplus.com,2005:PostPresenter/cms-24543PostCSS Quickstart Guide: Gulp Setup<p>In the <a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-instant-setup-options--cms-24536" target="_self">last tutorial</a> we covered how you can get started with PostCSS instantly using CodePen or Prepros. These options are great, but restrictive in that you don’t get to control which plugins are available for you to use. </p><p>In this tutorial we’ll go through how you can use PostCSS with the task runner <a href="http://gulpjs.com/" rel="external" target="_blank">Gulp</a>, allowing you to decide for yourself which plugins you want to use and hence really tap into the plugin ecosystem.</p><p><strong>Note</strong>: If you’ve never worked with command line or task runners before, I recommend that before you begin this tutorial you check out our free series: <a href="http://webdesign.tutsplus.com/series/the-command-line-for-web-design--cms-777" rel="external" target="_blank">The Command Line for Web Design</a>.</p><h3>Prerequisites</h3><p>Given we’ll be working with Gulp, we’ll assume you already have the prerequisites for its use installed:</p><ul>
<li>Node.js</li>
<li>NPM</li>
<li>Git</li>
</ul><p>If you’re not sure you have these installed, please follow the tutorial <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-taming-3rd-party-packages--cms-23451" rel="external" target="_blank">The Command Line for Web Design: Taming 3rd Party Packages</a> as it will take you through getting these prerequisites in place.</p><p>Please also ensure you understand the basics of Gulp use by following the tutorial <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-automation-with-gulp--cms-23642" rel="external" target="_blank">The Command Line for Web Design: Automation with Gulp</a>. Additionally, follow the instructions in the tutorial’s “Setup Project for Gulp” section. Before you move on you should have a project folder with:</p><ul>
<li>A “gulpfile.js” (Gulpfile) </li>
<li>A “package.json” file</li>
<li>Gulp installed in the “node_modules” folder and set as a dev dependency for your project</li>
</ul><h2>Basic Gulp PostCSS Setup</h2><p>Inside your project folder create two subfolders, one named “src” and one named “dest”. The “src” folder is going to hold your unprocessed CSS files, while the “dest” folder will have your PostCSS processed files written into it.<br></p><p>The next thing you’ll need to do is install the <a href="https://github.com/postcss/gulp-postcss" rel="external" target="_blank">gulp-postcss</a> plugin into your project - we’ll be using this to handle our PostCSS processing.</p><p>In a terminal/command prompt pointed at your project folder, run the command:</p><pre class="brush: bash noskimlinks noskimwords">npm install --save-dev gulp-postcss</pre><p>After the installation completes your project structure should look like this:</p><p><img alt="" data-src="https://cms-assets.tutsplus.com/uploads/users/53/posts/24543/image/gulpproject.png"></p><p>Now open up your Gulpfile for editing and create variables to call in both the “gulp” and “gulp-postcss” modules by adding the following code:</p><pre class="brush: javascript noskimlinks noskimwords">var gulp = require('gulp');
var postcss = require('gulp-postcss');</pre><p>We can now setup a task to read a source CSS file and process it through PostCSS. </p><p>Add the following:</p><pre class="brush: javascript noskimlinks noskimwords">gulp.task('css', function () {
var processors = [
];
return gulp.src('./src/*.css')
.pipe(postcss(processors))
.pipe(gulp.dest('./dest'));
});</pre><p>Let’s break down what we have in the code above.</p><p>In the first line we’ve setup a gulp task named <code class="inline">css</code>. This task executes a function, and inside that function we’ve created an array named <code class="inline">processors</code>. Right now that array is empty, but in a moment we’ll fill that with the PostCSS plugins we want to use.</p><p>After the <code class="inline">processors</code> array we’ve specified the files we want to target for processing: any CSS files in the “src” folder.</p><p>In the first of the two lines using the <code class="inline">pipe()</code> function, we’re setting PostCSS to execute via the function <code class="inline">postcss()</code>. As an argument through that function we’re passing our <code class="inline">processors</code> array, which, later, will tell PostCSS which plugins we want to use.</p><p>Finally, with the second of the two <code class="inline">pipe()</code> functions, we’re having our processed code written into a new CSS file in our “dest” folder.</p><h3>Run a Test Compile</h3><p>Go ahead and create a new “style.css” file in your “src” folder and add some test CSS to it such as:</p><pre class="brush: css noskimlinks noskimwords">.test {
background: black;
}</pre><p>Now in your terminal/command prompt, still pointed at your project folder, run the command:</p><pre class="brush: bash noskimlinks noskimwords">gulp css</pre><p>This will run the task you just setup, and as a result you should now find a new “style.css” file inside your “dest” folder.</p><p>When you open up this new file, you’ll see identical code in it to that of your source file. The code hasn’t changed because we haven’t used any PostCSS plugins yet, and as you’ll know from a previous tutorial, it’s the plugins which perform the actual CSS manipulations.</p><h2>Add PostCSS Plugins</h2><p>We’ll now add a selection of PostCSS plugins and packs: <a href="https://github.com/postcss/autoprefixer" rel="external" target="_blank">Autoprefixer</a> (adds vendor prefixes), <a href="http://cssnext.io/setup/" rel="external" target="_blank">cssnext</a> (enables future syntax) and <a href="https://github.com/jonathantneal/precss" rel="external" target="_blank">precss</a> (extends with Sass-like functionality).</p><p>Run the following commands to install each plugin into your project:</p><pre class="brush: bash noskimlinks noskimwords">npm install autoprefixer --save-dev
npm install cssnext --save-dev
npm install precss --save-dev</pre><p><strong>Note</strong>: The <code class="inline">cssnext</code> and <code class="inline">precss</code> installations may take a little while as they are packs of multiple plugins.</p><p>Next we’ll define variables to load in each one into our project. Add the following code under the two existing variables at the top of your Gulpfile:</p><pre class="brush: javascript noskimlinks noskimwords">var autoprefixer = require('autoprefixer');
var cssnext = require('cssnext');
var precss = require('precss');</pre><p>Then we’ll add these three plugins to the <code class="inline">processors</code> array in our gulp task. Update the array to the following:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
autoprefixer,
cssnext,
precss
];</pre><p>With the three plugins added to our processors array, PostCSS will know we wish to apply each one to our source CSS.</p><p>We’re now ready to add some test code to our “src/style.css” file and check that everything is working. Delete what you already have in the file and add this CSS instead:</p><pre class="brush: css noskimlinks noskimwords">/* Testing autoprefixer */
.autoprefixer {
display: flex;
}
/* Testing cssnext */
.cssnext {
background: color(red alpha(-10%));
}
/* Testing precss */
.precss {
@if 3 &lt; 5 {
background: green;
}
@else {
background: blue;
}
}</pre><p>Run the <code class="inline">gulp css</code> command again now, and the resulting file in your “dest” folder should have the following content:</p><pre class="brush: css noskimlinks noskimwords">/* Testing autoprefixer */
.autoprefixer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
/* Testing cssnext */
.cssnext {
background: rgba(255, 0, 0, 0.9);
}
/* Testing precss */
.precss {
background: green
}</pre><p>As per the above, you should see vendor prefixes have been added to the first class by Autoprefixer, an <code class="inline">rgba()</code> color has been output by cssnext in the second class, and the <code class="inline">@if @else</code> check has been evaluated by PreCSS in the third class.</p><h3>Setting Plugin Options</h3><p><strong>Note</strong>: if you want to configure options for a plugin, add a pair of brackets after its name in the preprocessors array and pass the options there. For example, you might specify the browser list you want Autoprefixer to work off, like so:</p><pre class="brush: javascript noskimlinks noskimwords"> var processors = [
autoprefixer({browsers: ['last 1 version']}),
cssnext,
precss
];</pre><h2>Sharing Your Project</h2><p>The beauty of PostCSS is in its ability to be configured with any combination of plugins. The challenge this brings forward, however, is ensuring that other people who wish to work on a project have the same setup of PostCSS plugins. Thanks to <a href="https://www.npmjs.org/" rel="external" target="_blank">npm</a>, this challenge is handled through its system of dependency management.</p><p>Because you are using the <code class="inline">--save-dev</code> flag every time you install a plugin into your project, it will be added to your “project.json” file as a dev dependency. This means if you want to share your project with others, they can run the command <code class="inline">npm install</code> on the package you share with them and have all the same plugins automatically installed.<br></p><p>To learn more about how dependency management works with NPM check out the tutorial <a href="http://webdesign.tutsplus.com/tutorials/the-command-line-for-web-design-taming-3rd-party-packages--cms-23451" rel="external" target="_blank">The Command Line for Web Design: Taming 3rd Party Packages</a>.</p><h2>Let’s Recap</h2><p>To summarize the above:</p><ul>
<li>Create an npm project with Gulp installed and a Gulpfile inside</li>
<li>Install the gulp-postcss plugin</li>
<li>Setup your Gulpfile to load the gulp and gulp-postcss plugins</li>
<li>Create a gulp task to compile your CSS</li>
<li>Within the task, setup a <code class="inline">processors</code> array</li>
<li>Pipe your source CSS through the <code class="inline">postcss()</code> function, with the <code class="inline">processors</code> array passed as an argument</li>
</ul><p>From there, you can follow the same essential steps to enable any PostCSS plugin in your project:</p><ul>
<li>Install the plugin into your project with <br><code class="inline">npm install &lt;plugin_name&gt; --save-dev</code>
</li>
<li>Define a variable to load the plugin in your Gulpfile e.g. <br><code class="inline">var autoprefixer = require('autoprefixer');</code>
</li>
<li>Add that variable name into your <code class="inline">preprocessors</code> array.</li>
</ul><p>Check out <a href="https://github.com/tutsplus/postcss-quickstart-guide-gulp-setup" target="_self">the Github repo</a> for starter files and completed examples.</p><h2>Coming Up Next: Grunt + PostCSS</h2><p>In <a href="http://webdesign.tutsplus.com/tutorials/postcss-quickstart-guide-grunt-setup--cms-24545" target="_self">the next tutorial</a> we’ll cover how to setup a PostCSS project in the other of the big two task runners: Grunt. See you there!</p>2015-10-01T15:58:47.000Z2015-10-01T15:58:47.000ZKezz Bracey