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

Dissecting issues with our processor

With a Gulp task file and associated package.json file in place, we should be good to go, right? Well, not quite—yes, our processor has been used on demos throughout the book to great effect. But there is more that we can do: our Gulp file should never be static; we should always look to review it periodically, to ensure it is working at optimal efficiency.

Note

To see an updated version of our Gulp file, take a look in the T49 – fixing issues in Gulpfile folder within the code download that accompanies this book.

Our Gulp file does have a few issues we need to address, so let's look at these now:

  • Some of our tasks are not correctly named—for example, the styles task could be renamed to better reflect that we're using Rucksack in this task.
  • There is a question about the use of source maps; so far we've used a dedicated source map plugin to create them. An upcoming change in Gulp 4 will reduce the need for a plugin—support for creating them is being added to Gulp core, so a separate plugin won't be required so often!
  • In the rename task, we've hard-coded a style.min.css filename as the output; this isn't going to suit all requirements, so we should change this to make it dynamic.
  • Staying with the rename task—we're combining two tasks, when they should be split into two separate processes.
  • Take a look at the processor list within the styles task at line 16; this isn't too bad now, but over time it could become long and awkward to read! Instead, we need to change it so that at the point of calling PostCSS, we can use an array instead to provide the names.
  • When creating source maps, our current setup provides both a full fat and minified version; is this really necessary? The issue comes from cssnano, which is compressing every .css file it sees; this isn't necessary, so needs to be changed.
  • The use of cssnano that should be run as a task within PostCSS is causing issues—even though it would make sense to run it this way, it needs to be run independently, to satisfy our needs.
  • We should make a decision on whether we use a dedicated plugin for providing vendor prefix support, or rely on the use of other plugins that may have this built in already.
  • When compiling source files, our processor is producing two minified files; one is correctly named, but the other is meant to be the uncompressed version for development purposes.

Over the next few pages, we will explore ways of fixing and improving our Gulp task file—it's key to understand that whilst many of these changes are specific to our task file, they are ones that may crop up for your future projects. Above all, it is essential that we should continually review our production process to ensure it is working as needed.

Let's begin the process of fixing and improving our Gulp file before we put it to test on a sample site.

Fixing our Gulp task file

It has to be said that there are a few issues we need to resolve—the key here is that none of them will stop our compilation process; we should consider them more as rough edges on a diamond, which need polishing to make our process sparkle (pun intended!).

Note

Please note, the line numbers in the next exercise refer to the unmodified version of the source code from the T48 – existing processor folder, prior to making any changes. If you want to keep existing copies of files, please move them prior to starting the exercise.

Okay, let's get cracking: there are a few changes to make, so we will start with the key task, which compiles the source file:

  1. For this process, we need a copy of the gulpfile.js file from the T48 – existing processor folder within the code download that accompanies this book; go ahead and save it as gulpfile.js at the root of our project area.
  2. The first change we need to make is to enable autoprefixer support in the file—you should find it there but commented out on line 5; go ahead and remove the comment.
  3. On or around line 16, look for this line:
    .pipe(postcss([ rucksack({ fallbacks: true, autoprefixer: true }) ]))

    We're not going to include fallback support, and will take care of autoprefixer separately, so for now, alter it as shown:

    .pipe(postcss([ rucksack(), autoprefixer() ]))
  4. Our next change is in the lint-styles task—two changes are required here; first, add this block at line 13, below the declaration for Rucksack:
    var stylerules = {
      "color-no-invalid-hex": 2,
      "declaration-colon-space-before": [2, "never"],
      "indentation": [2, 2],
      "number-leading-zero": [2, "always"]
    };
  5. Next, go ahead and replace the entire lint-styles task with this:
    gulp.task('lint', ['styles'], function() {
      return gulp.src("dest/*.css")
        .pipe(postcss([ stylelint({ "rules": stylerules }), 
        reporter({ clearMessages: true })
      ]))
    });
  6. In the rename task, we have three changes to make—first, remove the cssnano line at line 38; we're splitting the task into two, and this will be handled in a new task.
  7. This task has a prerequisite, which we've renamed—go ahead and change line 36 to this:
    gulp.task('rename', ['lint'], function () {
  8. Next, alter the rename command as indicated—this is on line 39:
    .pipe(rename(renameFunction))
  9. In the next task, sourcemap, we have one alteration to make—on or around line 47, change this line as shown:
    gulp.task('sourcemap', ['rename'], function () {
      return gulp.src(sourceMapLocation)
  10. We've talked about splitting out the minification task—go ahead and add this below the sourcemap task:
    gulp.task('minifyCSS', ['sourcemap'], function () {
      return gulp.src('dest/*.min.css')
        .pipe(cssnano({ autoprefixer: false }))
        .pipe(gulp.dest("dest/"));
    });
  11. We've made changes to the task names, so we need to update the default task and watch facility—look for the string of names in square brackets on or around lines 50 and 52. Replace it with this string:
    ['styles', 'lint' , 'rename' , 'sourcemap', 'minifyCSS']
  12. Our watch task can also be put on a diet—there is no need to specify all of the tasks twice! Instead, go ahead and change the code as indicated—when changes are made, the watch facility will run the default task, which already has the requisite tasks:
    gulp.task('default', ['styles', 'lint' , 'rename' , 'minifyCSS', 'sourcemap']);
    
    var watcher = gulp.watch('src/*.css', ['default']);
    watcher.on('change', function(event) {
  13. We're almost done—there are some additional declarations we need to add at the top of our file, to ensure everything works as expected. Below the stylerules declaration added in step 4, go ahead and add these extra lines:
    var renameFunction = function (path) {
      path.extname = ".min.css";
      return path;
    };
    
    var sourceMapLocation = ['dest/*.css', '!dest/*.min.css'];

We now have an updated Gulp task file—we now need to copy the style.css from the src folder under T49 – fixing issues in Gulpfile to the src folder at the root of our project area. If all is well, we should have something akin to this in the dest folder of our project area when we compile our file, and a file named style.css.map in the maps folder:

Fixing our Gulp task file

At this point, I am sure you will have a few questions about some of the changes we've made—the demo highlights a few key points, so it's worth taking time out to explore these in more detail.

Tip

If you come across any issues with changing the gulp file, then check out a completed version in the T49 - fixing issues in Gulpfile folder in the code download that accompanies this book.

Understanding the changes made

Throughout the course of our demo, we made a number of changes to our Gulp task file—the key thing to note is that none of them are compulsory. Our task file worked perfectly well prior to making the changes, so if they aren't compulsory, why are we making them?

The answer to this is simple—using a task runner such as Gulp is about automating processes so that you arrive at just the content you need. We had that, but the task runner produced extra files, didn't compress them as expected, and our Gulp file contained tasks that had multiple steps within the same task. The work we completed was about adding polish to the process—although our Gulp task file worked, we explored how we could improve on it by tweaking some of the processes.

We kicked off with changes to how vendor prefixes were added—our existing task completed this as part of compiling using the Rucksack plugin. The Rucksack plugin was to provide fallback support—I'm not a fan of working with older browsers, so we don't need it. This makes it less beneficial to incorporate vendor prefix support from such a large plugin, thus support is not enabled.

Note

There is another plugin available for PostCSS that handles vendor prefixes—doiuse, available at https://github.com/anandthakker/doiuse. Just another option to try!

The lint-styles task worked well—the changes we made focus on making the code easier to read in the task file. We moved the configuration block to the start of the file, and rearranged the format of the task; this means that we should not have to change the task, even though we may change the configuration!

Most of the remaining changes focus on splitting multiple roles into single tasks, and correcting some anomalies in the output. Our compilation process produced a minified file with the right extension, but also minified the original source file. We also had two source map files produced in a similar fashion—this is clearly not ideal! The changes we made now mean that our original source file is not minified, but only one minified file is produced, and that we have a single uncompressed style sheet created during the process.

Perfect, we now have a polished compilation process, which is producing the right files at the appropriate point; what next? Well, we can now add additional functionality to our compilation process. Using a task runner such as Gulp is about automating menial tasks, so let's explore what we might achieve in more detail.