Table of Contents for
Mastering PostCSS for Web Design

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Mastering PostCSS for Web Design by Alex Libby Published by Packt Publishing, 2016
  1. Cover
  2. Table of Contents
  3. Mastering PostCSS for Web Design
  4. Mastering PostCSS for Web Design
  5. Credits
  6. About the Author
  7. About the Reviewer
  8. www.PacktPub.com
  9. Preface
  10. What you need for this book
  11. Who this book is for
  12. Conventions
  13. Reader feedback
  14. Customer support
  15. 1. Introducing PostCSS
  16. Introducing PostCSS
  17. Setting up a development environment
  18. Creating a simple example using PostCSS
  19. Linting code using plugins
  20. Exploring how PostCSS works
  21. Summary
  22. 2. Creating Variables and Mixins
  23. Creating a hover effect example
  24. Transitioning to using PostCSS
  25. Adding variable support to PostCSS
  26. Updating our hover effect demo
  27. Setting the order of plugins
  28. Creating mixins with PostCSS
  29. Looping content with PostCSS
  30. Summary
  31. 3. Nesting Rules
  32. Navigating through pages
  33. Transitioning to using PostCSS plugins
  34. Exploring the pitfalls of nesting
  35. Making the switch to BEM
  36. Exploring our changes in more detail
  37. Summary
  38. 4. Building Media Queries
  39. Exploring custom media queries in PostCSS
  40. Making images responsive
  41. Adding responsive text support
  42. Optimizing media queries
  43. Retrofitting support for older browsers
  44. Moving away from responsive design
  45. Taking things further with CSS4
  46. Summary
  47. 5. Managing Colors, Images, and Fonts
  48. Managing fonts with PostCSS
  49. Creating image sprites
  50. Working with SVG in PostCSS
  51. Adding support for WebP images
  52. Manipulating colors and color palettes
  53. Creating color functions with PostCSS
  54. Summary
  55. 6. Creating Grids
  56. Creating an example with Bourbon Neat
  57. Exploring the grid plugins in PostCSS
  58. Transitioning to using PostCSS-Neat
  59. Creating a site using Neat and PostCSS
  60. Adding responsive capabilities
  61. Summary
  62. 7. Animating Elements
  63. Moving away from jQuery
  64. Making use of pre-built libraries
  65. Switching to using SASS
  66. Making the switch to PostCSS
  67. Exploring plugin options within PostCSS
  68. Updating code to use PostCSS
  69. Creating a demo in PostCSS
  70. Optimizing our animations
  71. Using our own animation plugin
  72. Summary
  73. 8. Creating PostCSS Plugins
  74. Dissecting the architecture of a standard plugin
  75. Creating an transition plugin
  76. Building a custom font plugin
  77. Simplifying the development process
  78. Guidelines for plugin building
  79. Making the plugin available for use
  80. Summary
  81. 9. Working with Shortcuts, Fallbacks, and Packs
  82. Exploring plugin packs for PostCSS
  83. Adding shortcuts with Rucksack
  84. Linting and optimizing your code
  85. Providing fallback support
  86. Summary
  87. 10. Building a Custom Processor
  88. Exploring our processor
  89. Dissecting issues with our processor
  90. Optimizing the output
  91. Adding reload capabilities
  92. Extending our processor further
  93. Testing the final pre-processor
  94. Getting started with some hints and tips
  95. Introducing the CSStyle library
  96. Summary
  97. 11. Manipulating Custom Syntaxes
  98. Preparing our environment
  99. Implementing custom syntax plugins
  100. Parsing CSS
  101. Formatting the output with the API
  102. Highlighting our syntax code
  103. Summary
  104. 12. Mixing Preprocessors
  105. Exploring the conversion process
  106. Introducing the Pleeease library
  107. Compiling with other preprocessors
  108. Using the PreCSS library
  109. Converting a WordPress installation
  110. Setting up our environment
  111. Considering the conversion process
  112. Making changes to our code
  113. Compiling and testing the changes
  114. Summary
  115. 13. Troubleshooting PostCSS Issues
  116. Exploring some common issues
  117. Getting help from others
  118. Summary
  119. 14. Preparing for the Future
  120. Converting CSS4 styles for use
  121. Supporting future syntax with cssnext
  122. Creating plugins to provide extra CSS4 support
  123. Summary
  124. Index

Switching to using SASS

As a developer or designer, if our development workflow includes the use of SASS, then the temptation is to use mixins such as this to construct our styles:

@mixin transition ($value...) {
  @if length($value) >= 1 { // If we set value
    @include prefixer($property: transition, $value: $value);
  } @else { // If value is not set, return default value
    @include prefixer($property: transition, $value: all 0.15s ease-in 0.05s);
  }
}

There's nothing wrong with this, but it will take effort to manage our mixins if we need to use more than just a small handful! The easier option is to explore using a pre-built animation library, as a way of reducing our development effort.

There are a number of developers who have created mixin libraries to handle animations; a perfect example is the SASS port of Animate, by Geoff Graham, which is available for download at https://github.com/geoffgraham/animate.scss.

There is something, though, that we have to be mindful of when working with mixins—it's all too easy to use them to manage vendor prefixes, such as this:

@mixin prefixer($property, $value) {
  -webkit-#{$property}: $value; // Attach webkit prefix (Chrome, Safary, Some Android native browsers)
  -moz-#{$property}: $value; // Attach moz prefix (FireFox)
  -o-#{$property}: $value; // Attach o prefix (Opera)
  #{$property}: $value; // no prefix (modern browsers and latest IE versions)
}

Although it will add the relevant vendor prefixes when the code is compiled, it's not considered best practice.

The onus is on us to ensure that each animation includes all of the relevant vendor prefixes—with the best will in the world, it's a challenge to keep up! There is also the issue of adding rules that won't have any effect—for example, there is no point in adding –o as a prefix for transition; this prefix is no longer needed.

Fortunately, there is a better way to handle prefixes—we can use Autoprefixer (from https://twitter.com/autoprefixer) to automatically handle vendor prefixes for us. The great thing about Autoprefixer is that it uses the Can I Use (http://www.caniuse.com) database to keep details up to date.

There are various plugins available that allow us to use task runners such as Grunt or Gulp. We can of course use a standalone GUI-based compiler for this purpose, but why run something like this when we can tie in much more functionality when using a task runner? We can even use any one of several plugins to remove vendor prefixes, prior to running a new compilation—this will ensure any redundant prefixes are removed.

With this in mind, let's get practical. For our next demo, we're going to construct a simple gallery effect, which showcases the same animations we saw earlier, but this time using the SASS version of Animate.css. We'll use Gulp as our task runner to compile the SASS code, before adding a source map, checking our code for consistency, adding vendor prefixes, and so on. You get the idea!

Suffice to say that we can do a lot using a task runner, so without further ado, let's get started with constructing our gallery.

Creating an animated gallery

Animating content can be a double-edged sword. Added with care, it can really lift a site to the next level. If it is done badly, then patronage of the site is likely to drop like a stone!

In our last demo, we constructed a simple gallery effect—this was more to show off the different types of animated effects we can add, rather than produce something that would win awards. Over the next few pages, we'll continue with our demo, but this time reconfigure it to use the SASS version of Animate.css. We will also introduce the use of a task runner to compile our code—as this is a requirement for using PostCSS, it seems a perfect point to start using it, as the final part of our transition to working with animation and PostCSS.

Note

The files for this tutorial are available in the T38 folder in the accompanying code download.

Without further ado, let's add the changes to our previous demo:

  1. We need to download the SASS version of Animate—it's available from https://github.com/geoffgraham/animate.scss/archive/master.zip. Go ahead and extract the contents of Animate.scss-master into the src folder at the root of our project area.
  2. In the src folder, rename the Animate.scss file to _animate.scss—this is to indicate that it is a partial, which prevents it being compiled as a separate file by the SASS compiler.
  3. In the src folder, go ahead and rename it as style.scss—this changes it to a SASS file, which is required for compilation later in the exercise. We should have something akin to this screenshot in our src folder:
    Creating an animated gallery
  4. Go ahead and open up the style.scss file. At the bottom, add this line at the top of the stylesheet:
    @import "_animate.scss";
  5. Next, add the following additional lines at the end of the stylesheet—these pull in the animations from the SASS version of Animate.css; the timing has also been extended to five seconds, as the original example was too quick:
    .bounce { @include bounce(); }
    .flip { @include flip(); }
    .hinge { @include hinge(); }
    .flash { @include flash(); }
    .shake { @include shake(); }
    .swing { @include swing(); }
    
    .animated:hover {
      animation-duration: 5s;
      animation-fill-mode: both;
    }

  6. Save the file, then copy the contents of the src folder under T38 to the src folder at the root of our project area—we will be compiling this file shortly.
  7. In a new file, go ahead and add the following code, then save it as gulpfile.js to the root of our project area—this will form our gulp file, which we will use to compile our code:
    'use strict';
     
    var gulp = require('gulp');
    var postcss = require('gulp-postcss');
    var sass = require('gulp-sass');
    
    gulp.task('sass', function () {
      return gulp.src('src/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('dest/'));
    });
    
    gulp.task('default', ['sass']);
    
    var watcher = gulp.watch('src/*.scss', ['sass']);
    watcher.on('change', function(event) {
      console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
  8. We also need a package.json file—this will store details of the plugins we will be using. For now, we will limit ourselves to using gulp-sass, but this will soon change! Go ahead and add the following lines to a new file, saving it as package.json in the root of our project area:
    {
      "name": "postcss",
      "version": "1.0.0",
      "description": "Configuration file for PostCSS",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "Alex Libby",
      "license": "ISC",
      "dependencies": {
        "postcss": "^5.0.8"
      },
      "devDependencies": {
        "gulp": "^3.9.0",
        "gulp-postcss": "^6.0.0",
        "gulp-sass": "^2.1.1"
      }
    }
  9. The keen-eyed among you should spot that we've not installed the gulp-sass plugin. Let's fix that now by firing up a Node.js command prompt, then changing the working directory to the project area. Go ahead and run this command from the prompt:
    npm install gulp-sass --save-dev
    
  10. At the prompt, enter gulp then press Enter—Gulp will now go away and compile our file; if all is well, we should see a compiled style sheet appear in the dest folder of our project area.
  11. At this point, try running animate.html in a browser—if all is well, we should see no change to our gallery effect, but can be safe in the knowledge that we're now using the SASS version of Animate.css.

Our demo has now been converted to using Animate.scss—we could easily have chosen to use any one of several compilers (such as Koala—http://www.koala-app.com), but instead chose to use Gulp. It acts as a perfect route into making the transition to using PostCSS—as we've seen in earlier demos, we've already used a task runner in the form of Gulp for this purpose. This allows us to make that gradual transition—when all of the SASS elements have been converted, we simply drop the task from within our gulp file to complete the transition.

Adding the finishing touches

So, what next? We've created a basic gulp task file, which we used to compile our SASS code to valid styles.

But this is just a small part of the story; we need to add a lot more to make our compilation process useful and ready for conversion to using PostCSS.

Let's get started:

  1. The first change we need to make is in the package.json file—go ahead and add the lines as highlighted:
        "cssnano": "^3.2.0",
        "gulp": "^3.9.0",
        "gulp-postcss": "^6.0.0",
        "gulp-rename": "^1.2.2",
        "gulp-sass": "^2.1.1",
        "gulp-sourcemaps": "^1.5.2",
        "postcss-reporter": "^1.3.0",
        "stylelint": "^2.3.7"
      }
    }
  2. Next, we need to configure our gulp file with some additional tasks—the first task is to add references to some additional plugins that we've already used from earlier in the book. Go ahead and add the following highlighted lines:
    var sass = require('gulp-sass');
    var autoprefixer = require('autoprefixer');
    var cssnano = require('cssnano');
    var sourcemaps = require('gulp-sourcemaps');
    var rename = require('gulp-rename');
    var stylelint = require('stylelint');
    var reporter = require('postcss-reporter');
  3. With the additional plugin references added, we now need to add in our extra tasks—immediately below the SASS task, add in this task; this manages the linting of our code, for consistency:
    gulp.task("lint-styles", ['sass'], function() {
      return gulp.src("dest/*.css")
        .pipe(postcss([ stylelint({
          "rules": {
            "color-no-invalid-hex": 2,
            "declaration-colon-space-before": [2, "never"],
            "indentation": [2, 2], 
            "number-leading-zero": [2, "always"]
          }
        }),
        reporter({
          clearMessages: true,
        })
      ]))
    });
  4. Add this next task immediately below the previous step—this renames the files as part of the minification process:
    gulp.task('rename', ['lint-styles'], function () {
      return gulp.src('dest/*.css')
        .pipe(postcss([ cssnano() ]))
        .pipe(rename('style.min.css'))
        .pipe(gulp.dest("dest/"));
    });
  5. Our next gulp task manages the generation of source maps—this can be done within SASS automatically, but using a separate plugin allows flexibility during compilation. Go ahead and add this task immediately below the previous one:
    gulp.task('sourcemap', ['rename'], function () {
      return gulp.src('dest/*.css')
        .pipe(sourcemaps.init())
        .pipe(sourcemaps.write('maps/'))
        .pipe(gulp.dest("dest/"));
    });
  6. We're almost at the end—go ahead and alter these lines as indicated:
    gulp.task('default', ['sass', 'lint-styles', 'rename', 'sourcemap']);
    
    var watcher = gulp.watch('src/*.scss', ['sass', 'lint-styles', 'rename', 'sourcemap']);
    watcher.on('change', function(event) {
      console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
  7. Save the file. Go ahead and fire up a Node.js command prompt, then change the working folder to our project area.
  8. At the prompt, type in gulp then press Enter—Gulp will go away and compile our file.
  9. If we take a look in the dest folder, we should see the same compiled style.css file, but this time with accompanying minified versions of the source map and style sheet:
    Adding the finishing touches

If we preview the results of our work, we should see no change in functionality within the demo, but can be safe in the knowledge that we now have minified versions of our files available for use—after all, it is always better to use minified files in a production environment!

We've now laid the groundwork for our conversion to using PostCSS—the keen-eyed among you should spot that the plugin reference for PostCSS has already been added to our gulp file, ready for the next stage in our conversion process. Everything is now in place in our gulp file, save for the SASS task – at the appropriate point we will remove the SASS task and replace it with a PostCSS equivalent; this will take place in our next exercise. Before we do so, it's worth taking a little time to explore what is available within the PostCSS ecosystem—although there isn't a great deal on offer, we can still produce usable code for compilation within PostCSS.