Webpack 3 Sass cssnano Autoprefixer Workflow

Autoprefixer

Install this PostCSS plugin that adds vendor prefixes to CSS rules by referencing Can I Use data.

npm install --save-dev autoprefixer

Create a PostCSS configuration module in the project root for requiring the autoprefixer plugin.

postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

Autoprefixer uses the browserlist library to target browsers. Configure autoprefixer browser support by adding a list of supported browsers to the package.json file. In this example, we target browsers greater than 1% according to global usage statistics and Internet Explorer versions greater than 9.

package.json
{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "browserslist": [
    "> 1%",
    "ie > 9"
  ],

  ...
}

npm-run-script

To run a webpack build, add "build": "webpack" to the package’s “scripts” object.

package.json
...

  "browserslist": [
    "> 1%",
    "ie > 9"
  ],
  "scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...
}

Update the run scripts with a dev script command to watch files and build whenever updates are saved. Additionally, add some flags to the dev and build scripts for the console output.

package.json
...

  "scripts": {
    "dev": "webpack --watch --progress --colors",
    "build": "webpack --progress --hide-modules",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...
}

Demo

Some Sass known to require vendor pre-fixes is needed to test and demo the build. For example, create a src/sass folder and add these scss files.

main.scss
@import 'modules/js';
@import 'modules/loading';

Create a modules folder in the sass folder for these two files.

_js.scss
// classes used in javascript events

.jshide {
    display: none;
}
_loading.scss
/* Absolute Center Spinner */
.loading {
    position: fixed;
    z-index: 999;
    height: 2em;
    width: 2em;
    overflow: show;
    margin: auto;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;

    /* Transparent Overlay */
    &:before {
        content: '';
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0,0,0,0.3);
    }
}

/* :not(:required) hides these rules from IE9 and below */
.loading:not(:required) {
      /* hide "loading..." text */
      font: 0/0 a;
      color: transparent;
      text-shadow: none;
      background-color: transparent;
      border: 0;
}

.loading:not(:required):after {
      content: '';
      display: block;
      font-size: 10px;
      width: 1em;
      height: 1em;
      margin-top: -0.5em;
      animation: spinner 1500ms infinite linear;
      border-radius: 0.5em;
      box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0, rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0, rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) -1.5em 0 0 0, rgba(0, 0, 0, 0.75) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0;
}

/* Animation */
@-webkit-keyframes spinner {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
@-moz-keyframes spinner {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
@-o-keyframes spinner {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
@keyframes spinner {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

Create an index.html file in the project root to output the running demo in a web browser.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Loading Spinner Demo</title>
    <link rel="stylesheet" href="dist/style.css">
</head>
<body>
    <div class="loading jshide">Loading…</div>
    <button>Load</button>
    <script>

        var div = document.querySelector('div'),
            btn = document.querySelector('button');

        btn.addEventListener('click', function() {

            div.className = 'loading';

            btn.disabled = true;

            setTimeout(function() {

                btn.disabled = false;

                div.className = 'loading jshide';

            }, 3000);

        }, false);

    </script>
</body>
</html>

Build

Run the dev or build command from the package.json scripts object. Webpack outputs the processed style.css file into the dist folder.

npm run dev
npm run build
Source Code

Published by

Jim Frenette

Web Developer – views here are my own except those taken from people more clever than me.

Loading Disqus Comments ...
Loading Facebook Comments ...