Webpack 3 Sass cssnano Autoprefixer Workflow

Basic Webpack 3 Sass preprocessor workflow using cssnano for postprocessing minification and optimization. The Autoprefixer PostCSS plugin is also included in this configuration to automatically add vendor prefixes for only the browsers that need to be supported.

Before getting started, install Node.js and NPM. The default package manager for the Node.js JavaScript runtime environment, NPM is included with the Node.js installation.

Project

Navigate to the project root in your CLI, such as Terminal in OS X, PowersShell in Windows.

Enter npm init to interactively create a package manifest file named package.json. As dependencies are installed using the --save-dev option, this file will be updated so the entire project can be installed elsewhere using npm install or with its shorthand alias npm i.

npm init

Webpack 3

Webpack is a module bundler that generates static assets representing modules and their dependencies from a generated dependency graph. This enables a modular approach to web development that can be extended by using loaders with tasks that are performed when bundling files together.

Webpack version 3 was released earlier this year and as of this writing, version 3.8.1 is the latest. Install the latest version using npm install.

npm install --save-dev webpack

Open the project folder in a code editor, such as VS Code. Inspect the package.json file, webpack with its version number should now be listed under the devDependencies node. For example:

package.json
{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.8.1"
  }
}

Webpack Configuration

Create a new JavaScript file in the project root named webpack.config.js. At the top of this file define these required modules as constants: path, webpack and extract-text-webpack-plugin.

webpack.config.js
const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')

We’ve already installed webpack, and path is a core node module. Let’s install the Extract Text Plugin that will be used to extract the css from the bundle into a separate file.

npm install --save-dev extract-text-webpack-plugin

Next, create the webpack configuration object to export to the CLI.

webpack.config.js
...

module.exports = {
  context: path.resolve(__dirname, './src'),
  entry: {
    /* app: './js/index.js',*/
    css: './sass/main.scss',
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'bundle.js'
  },
  module: {
    rules: [
    {
      test: /\.(css|scss)$/,
      use: ExtractTextPlugin.extract({
        // TODO - Add Loaders
      })
    }]
  },
  plugins: [
    new ExtractTextPlugin('style.css'),
  ]
}
  • Throughout this tutorial you will encounter an ellipsis … in the code examples. These are not a part of the code and are there only to denote code that is being skipped and not applicable to the example. To view the entire file, examine the source code.

Install Loaders

Before we define the loaders in the webpack configuration, let’s install them.

SASS Loader compiles Sass to CSS and since it requires node-sass, install both sass-loader and node-sass.

npm install --save-dev sass-loader node-sass

PostCSS Loader processes CSS with PostCSS.

npm install --save-dev postcss-loader

CSS Loader resolves import at-rules and url functions in the CSS.

npm install --save-dev css-loader

Style Loader inlines <style></style> in the DOM.

npm install --save-dev style-loader

Define Loaders

In our configuration, we are extracting the CSS to its own file with the ExtractTextPlugin. Therefore we will define our loaders for processing Sass and CSS in the plugins use option. The fallback option is used when the CSS is not extracted.

webpack.config.js
...

  module: {
    rules: [
    {
      test: /\.(css|scss)$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
          {
            loader: 'css-loader',
            options: {
              minimize: true || {/* CSSNano Options */}
            }
          },
          {
            loader: 'postcss-loader'
          },
          {
            loader: 'sass-loader'
          }
        ]
      })
    }]
  },
  • Note that the loaders are ordered from bottom to top or right to left. Loaders act like functions, that’s why it’s from right to left. For example, css-loader(postcss-loader(sass-loader(resource)))

The next page covers installing and configuring the Autoprefixer PostCSS plugin, running the Webpack build and creating demo Sass and html to test the output.


Sass Workflow Using cssnano and Autoprefixer

This Sass preprocessor workflow uses cssnano for postprocessing minification and optimization that includes Autoprefixer to add vendor prefixes for only the browsers that need to be supported. UPDATE: Webpack 3 version (11-12-2017)

Autoprefixer

Without Autoprefixer, adding in vender prefixes is done in the Sass code, typically with a mixin to append every known prefix for a property. This more advanced mixin to prefix properties at least accepts prefix parameters for more control over which ones to use. However, you still need to include the mixin with applicable parameters throughout your Sass code which requires knowing which properties might need prefixes.

With Autoprefixer, you do not need to think at all about which properties need prefixes. Simply use only the-un prefixed property name in your Sass or CSS code and Autoprefixer will check the Can I use database to append prefixes as needed while understanding the specification differences.

cssnano

I don’t think I could write it any better than the folks at cssnano did, cssnano takes your nicely formatted CSS and runs it through many focused optimisations, to ensure that the final result is as small as possible for a production environment.. cssnano includes Autoprefixer in it’s list of transforms, therefore, when you install cssnano you also get Autoprefixer.

Workflow

This simple workflow uses the Gulp streaming build system to process the Sass code, add vendor prefixes with Autoprefixer via cssnano to optimize into production ready css. In this gulpfile.js, note cssnano’s autoprefixer option which accepts an array of browsers to support.

gulpfile.js
'use strict';

var gulp         = require('gulp'),
    cssnano      = require('gulp-cssnano'),
    sass         = require('gulp-sass');

var supported = [
    'last 2 versions',
    'safari >= 8',
    'ie >= 10',
    'ff >= 20',
    'ios 6',
    'android 4'
];

gulp.task('css', function(){
    return gulp.src(['src/sass/**/*.scss'])
        .pipe(sass())
        .pipe(cssnano({
            autoprefixer: {browsers: supported, add: true}
        }))
        .pipe(gulp.dest('css'));
});

Run the Workflow Example

In order to use the Node Package Manager (NPM) and Gulp task runner used in this workflow example, you will need to install Node.js.

Using a Command shell in the project root, follow these steps to get the local development environment setup.

Create package.json

The package.json file contains project metadata and lists dependencies that are available on npm. This is useful to have when you want to re-install or update the dependencies with the npm install command.

# create package.json
npm init

Install node modules

# install dependencies and save to package.json
npm install gulp --save-dev
npm install gulp-cssnano --save-dev
npm install gulp-sass --save-dev

Workflow Example Folders and Files

    • src
      • sass
        • modules
          • _js.scss
          • _loader.scss
        • main.scss
    • gulpfile.js
    • index.html
    • package.json
source code

Responsive Sidebar

This code sample shows how to create a responsive sidebar that fills the entire height of the page. Other CSS features include a fixed background image and universal box sizing with inheritance.

demo

Element Count

This code sample shows a CSS only solution to define different styles for an element based on the total number of elements. This is handy when you have dynamic list content and want to style it differently for a certain number of list items.

demo

li {
    width: 49%;
    display: inline-block;
    text-align: center;
}
/* three items */
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33%;
}

SASS Version

li {
    width: 49%;
    display: inline-block;
    text-align: center;
}
@for $i from 3 through 5 {
    li:first-child:nth-last-child(#{$i}),
    li:first-child:nth-last-child(#{$i}) ~ li {
        width: #{100%/$i}
    }
}

Animation

This code sample shows how to animate a background image using CSS.

HTML
<div class="banner-ani"></div>
CSS
.banner-ani {
    background-image: url(/sandbox/ui/assets/image/cool-dog-bg.png);
    background-color: transparent;
    background-position: 0px -196px;
    background-repeat:no-repeat;
    width: 230px;
    height: 196px;

    /* 
    after 2 seconds, provide a 1.5 second animation
    of the background image scrolling down from its
    pre-existing position of 0 -196px to 0 0

    css animation does not work in <= ie9 
    */
    -webkit-transition:all 1.5s ease;
    -moz-transition:all 1.5s ease;
    -webkit-animation: animatedBrandshopBannerBackground 1.5s 2s linear;
    -moz-animation: animatedBrandshopBannerBackground 1.5s 2s linear;
    animation: animatedBrandshopBannerBackground 1.5s 2s linear;

    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}
@keyframes animatedBrandshopBannerBackground {
    from { background-position: 0 -196px; }
    to { background-position: 0 0; }
}

demo


This code sample shows how to animate a background image using CSS and jQuery.

CSS
.banner-ani {
    background-image: url(/sandbox/ui/assets/image/cool-dog-bg.png);
    background-color: transparent;
    background-position: 0px -196px;
    background-repeat:no-repeat;
    width: 230px;
    height: 196px;
}
JavaScript & jQuery
$(function($){
    /*
    after 2 seconds, provide a 1.5 second animation
    of the background image scrolling down from its
    pre-existing position of 0 -196px to 0 0

    jquery plugin required: jquery.bgpos.js
    */
    var id,
        $bannerani = $('.banner-ani'),
        animate = function() {
            $bannerani.stop().animate({backgroundPosition:"(0 0)"}, {
                duration:1500,
                complete: function(){
                    console.log('Animation Completed');
                }
            });
        };

    clearTimeout(id);
    id = setTimeout(animate(), 2000);

});

demo

Responsive Hotspots

This code sample shows how to create hotspots for a responsive image entirely in CSS and HTML. When the image scales according to changes in viewport width, the hotspots and their respective tool tips will move accordingly.

demo

Centering Content

Horizontal centering

This is pretty straight forward and not an issue for consistent cross browser results. There are a couple of ways to horizontally center content. Skip ahead and read about vertical centering here.

text-align: center

Apply this declaration to the parent element and images and text will center. Note that the Text Block element does not center. However, all text and images are centered.

demo-1

Text Block

demo-1 CSS

.demo-1 {
    text-align: center;
}
.demo-1-img {
    width: 50%;
    max-width: 300px;
    margin: 20px;
}
.demo-1-text-block {
    display: block;
    width: 50%;
    max-width: 300px;
    margin-bottom: 20px;
    padding: 6px;
    background-color:#e6e6e6;
}

demo-1 HTML

<div class="demo-1">
    <img class="demo-1-img" src="/wp-content/uploads/2015/05/kingston.jpg" />
    <div class="demo-1-text-block">Text Block</div>
</div>
display: inline-block

When the display property of the Text Block is set to inline-block, text align: center aligns the div element.

demo-1.1

Text Block

demo-1.1 CSS

.demo-1 {
    text-align: center;
}
.demo-1-img {
    width: 50%;
    max-width: 300px;
    margin: 20px;
}
.demo-1-text-inline-block {
    display: inline-block;
    width: 50%;
    max-width: 300px;
    margin-bottom: 20px;
    padding: 6px;
    background-color:#e6e6e6;
}

demo-1.1 HTML

<div class="demo-1">
    <img class="demo-1-img" src="/wp-content/uploads/2015/05/kingston.jpg" />
    <div class="demo-1-text-inline-block">Text Block</div>
</div>
margin: auto

Apply this declaration to the element that you want to center. So, in order to center the Text Block, replace margin-bottom: 20px; with margin: 0 auto 20px auto; which is shorthand for margin-top: 0; margin-right: auto; margin-bottom: 20px; margin-left: auto;.

demo-2 CSS

/* demo-2 nearly identical to demo-1 css except for
margin: 0 auto 20px auto; in .demo-2-text-block */
.demo-2 {
    text-align: center;
}
.demo-2-img {
    width: 50%;
    max-width: 300px;
    margin: 20px;
}
.demo-2-text-block {
    display: block;
    width: 50%;
    max-width: 300px;
    margin: 0 auto 20px auto;
    padding: 6px;
    background-color:#e6e6e6;
}

demo-2

Text Block

Vertical centering

This can be an issue for consistent cross browser results when IE 8 needs to be supported, especially when the height of the parent element varies. Here are a couple of ways to vertically center content.

Flexbox demo-3

This is the modern approach, a browser support table can be referenced at Can I use. If you don’t need to support IE9 or lower, you don’t need to use floated layouts with flexbox.

demo-3

Vertically and horizontally centered multi-line text in a dynamically sized responsive container.

demo-3 CSS

.centering-content-demo-3 {
    padding: 10px;
    display: -webkit-box;
    display: -webkit-flex;
    display: -moz-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-align: center;
    -ms-flex-align: center;
    -webkit-align-items: center;
    align-items: center;
}
.demo-3-left,
.demo-3-right {
    padding: 10px;
    width: 50%;
}
.demo-3-left img {
    width: 100%;
}

demo-3 HTML

<div class="centering-content-demo-3">
    <div class="demo-3-left">
        <img src="/wp-content/uploads/2015/05/kingston.jpg" />
    </div>
    <div class="demo-3-right">
        Vertically and horizontally centered multi-line text in a dynamically sized responsive container.
    </div>
</div>
display: table-cell

For browsers that do not support flexbox, using the same HTML as demo-3 above, display: table-cell with vertical-align: middle will work for IE 9, IE 8, Android 4.3 and 4.1.

demo-4 CSS

.centering-content-demo-4 {
    padding: 10px;
    align-items: center;
}
.demo-4-left,
.demo-4-right {
    display: table-cell;
    vertical-align: middle;
    padding: 10px;
    width: 50%;
}
.demo-4-left img {
    width: 100%;
}

demo-4

Vertically and horizontally centered multi-line text in a dynamically sized responsive container.

Images Larger than Container

This will center the image inside of a element when the elements height and/or width is smaller than the image. This works well when you have image assets of various aspect ratios that you want to display as thumbs that are the same size.

ul#images-edit li {
    float: left;
    height: 100px;
    margin: 0 8px 8px 0;
    overflow: hidden;
    position: relative;
    width: 100px;
}
ul#images-edit li img {
    position: absolute;
    top: -9999px;
    bottom: -9999px;
    left: -9999px;
    right: -9999px;
    margin: auto;
    width: 150px;
}

Bootstrap Customization

This tutorial covers using Git to clone, branch and merge the latest Bootstrap source code, modifying and compiling your modifications to the source LESS variables using Grunt and viewing your compiled changes with a local Node.js web server.

If you are not familiar with Git, Node.js and Grunt, please read my previous post, Grunt JavaScript Task Runner to help get you started.

You could just use the Bootstrap customize and download form to customize the LESS variables and download a pre-compiled Bootstrap package. However, as of this writing, the user interface at the form doesn’t provide a preview option to monitor your changes before you download the package. And since the Bootstrap version 3 source now includes Grunt, we can use it to compile the LESS source and preview the changes via localhost.

Source Code

Using Git, clone the Bootstrap repository. To keep our changes to the source separate and to make upgrading the bootstrap source easier, create a develop branch.

# git clone creates the bootstrap directory in your current directory
$ git clone https://github.com/twbs/bootstrap.git

# create and checkout develop branch
$ git checkout -b develop

Load a Bootstrap example

I like to use the Node.js web-server.js that is bundled with the AngularJS tutorial. For example, here is how I start the NodeJs web-server.js that is included in the angular-phonecat repository on GitHub. This example presumes your CLI is in the bootstrap directory and the angular-phonecat repository is cloned to its own directory one level up.

UPDATED 1/4/2014

Repository contents rearranged over the holidays and the examples have been moved to the docs folder. You can always take a look at the latest source on GitHaub.

# directory structure (partial)
# | angular-phonecat/
#   | -- scripts/
#     | -- web-server.js
# | bootstrap/
#   | -- docs/
#     | -- examples/
#       | -- starter-template/
#         | -- index.html
#         | -- starter-template.css

# start the web server from the bootstrap directory
$ node ../angular-phonecat/scripts/web-server.js

Http Server running at http://localhost:8000/

Now open a web browser and go to http://localhost:8000/docs/examples/starter-template/index.html.

Modify LESS variables

Open the bootstrap/less/variables.less file in a text editor and find the @navbar-inverse-color and @navbar-inverse-link-color variables and change their values from @gray-light to @gray-lighter. Also, find @navbar-inverse-bg and change its value to #FF8C00.

Install node modules and compile LESS

The Bootstrap source contains a package.json for node module installation and a fully configured gruntfile.js to run Grunt tasks.

Open another bash window CLI and navigate to the bootstrap directory to install the node modules. After the node modules are installed, run the Grunt dist-css task which compiles the less files to dist/css/ followed by task dist-docs which copies the css files created in the previous task to docs/dist/css/.

# install node modules
$ npm install

# run grunt task to compile less to dist/css/
$ grunt dist-css

# run grunt task to copy to docs/dist/css/
$ grunt dist-docs

Refresh the web browser to see the compiled changes. The navigation bar at the top of the document in the starter template should now be orange instead of black.

Upgrading the source

Since we are only modifying the variables.less file from the source, upgrading is not that difficult. Using Git, merge the newer Bootstrap source master branch into the develop branch we created.

# checkout master branch
$ git checkout master

# get the latest bootstrap source
$ git pull origin master

# checkout develop
$ git checkout develop

# merge master into it
$ git merge master

Grunt JavaScript Task Runner

This tutorial describes how to setup and use the Grunt JavaScript task runner to automate repetitive tasks such as minification and compilation. Grunt is installed using npm, the Node.js package manager. You will also need Git to work with the tagged source code. This makes it easy to reset and compare your working copy of the code at each step. I discovered commit tags while using the AngularJS tutorial.

If you have not done so already, make sure that you have Node.js, Grunt CLI and Git installed. For Windows systems, after installing Git, you may decide to use the Git bash shell for your CLI (command line interface) instead of the Command Prompt.

Install Grunt’s command line interface (CLI) globally.

#install grunt CLI
$ npm install -g grunt-cli

Source Code

Using Git, clone the GruntTutorial repository. This contains all the source code for the tutorial. As you work through the tutorial, you will be instructed to use git to reset the source code so it matches the step at that point. This will revert the source code to it’s original state for the respective tag and thus overwrite any changes you have made to it.

# git clone creates the GruntTutorial directory in your current directory
$ git clone https://github.com/jimfrenette/GruntTutorial.git

# reset to step 0
$ git checkout -f step-00

Step 1: Node.js Package

# reset to step 1
$ git checkout -f step-01

A npm (nodejs package manager) package.json file is added to the project root for npm to read its structure and know what to do when installing it.

Update: 12-20-2014 — Interactively create a package.json file with the npm init command. More information available at the npm cli commands doc.

# create package.json
$ npm init

Grunt and node modules are installed per the package.json dependencies.

package.json
{
  "name": "grunt-tutorial",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-jshint": "~0.6.3",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2"
  }
}

These node_modules are already included in the step-01 source. To verify the process on your own, reset the tutorial source code to step-00 and run these npm install commands:

GruntTutorial – bash
# install the latest Grunt in your project folder
$ npm install grunt --save-dev

# install dependencies per package.json
$ npm install

Step 2: Combine and Minify Javascript files

# reset to step 2
$ git checkout -f step-02

Gruntfile.js is added to root of the project to specify the modules configuration, define tasks and load plugins. This Gruntfile.js specifies an uglify plugin to perform JavaScript minification. The banner option creates a comment on the first line of the minified file that is output. The JavaScript source (src) and destination (dest) paths are set in the build properties. Since our build source path has a wildcard * before the js filename extension, all of the js files in that directory will be minified into a single JavaScript file named grunt-tutorial.min.js as specified in the build destination property.

module.exports = function(grunt) {
  'use strict';
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/js/*.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });
  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  // Default task(s).
  grunt.registerTask('default', ['uglify']);
};

Time to test our Gruntfile.

# run the default task
$ grunt

You should recieve a message like this

Running "uglify:build" (uglify) task
File "build/js/grunt-tutorial.min.js" created.

Done, without errors. 

Step 3: Compass and Watch Plugin Install

# reset to step 3
$ git checkout -f step-03
OS X / Linux

For the Sass compile with the Compass & Watch Grunt plugins, you will need to have Ruby, Sass, and Compass version 0.12.2 or greater installed. Ruby comes pre-installed on OS X.

Windows

For the Sass compile with the Compass & Watch Grunt plugins, you will need to have the RubyInstaller for Windows. As of this writing, use Ruby 1.9.3 installers. These provide a stable language and a extensive list of packages (gems) that are compatible and updated. During the setup, check the option to Add Ruby executables to your PATH. After installing Ruby, install Sass and Compass using the Start Command Prompt with Ruby.

Start Command Prompt with Ruby
Start Command Prompt with Ruby

Install compass and watch Grunt plugins

By running these npm install commands with –save-dev, the package.json file will automatically be updated to include these two new dependencies.

GruntTutorial – bash
# install plugins and update package.json 
$ npm install grunt-contrib-compass --save-dev

$ npm install grunt-contrib-watch --save-dev

Compass and watch Grunt plugins added to the package.json devDependencies.

package.json
{
  "name": "grunt-tutorial",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-contrib-jshint": "~0.6.3",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2",
    "grunt-contrib-compass": "~0.6.0",
    "grunt-contrib-watch": "~0.4.4"
  }
}

Step 4: Sass

# reset to step 4
$ git checkout -f step-04

Sass .scss files added to the source (src) directory and the Gruntfile.

Gruntfile.js
module.exports = function(grunt) {
  'use strict';
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    compass: {
      dev: {
        // http://compass-style.org/help/tutorials/configuration-reference/#configuration-properties
        // these options will override (or extend) config.rb settings.
        options: {  
          cssDir: 'build/css/',
          sassDir: 'src/sass/'
        }
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/js/*.js',
        dest: 'build/js/<%= pkg.name %>.min.js'
      }
    },
    watch: {
      css: {
        files: '**/*.scss',
        tasks: ['compass']
      }
    }
  });
  // Load the plugins.
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  // Default task(s).
  grunt.registerTask('default', ['uglify', 'watch']);
};

Time to test our Gruntfile.

# run the default task(s)
$ grunt

Step 5: Compile Sass

# reset to step 5
$ git checkout -f step-05

The CLI / Terminal shows the status of the Grunt tasks that are run.

# run the default task(s)
$ grunt

Running "uglify:build" (uglify) task
File "build/js/grunt-tutorial.min.js" created.

Running "watch" task
Waiting...OK

Edit and save one of the Sass (.scss) files. The watch task waits for changes to files and then fires a task. In our Gruntfile, the watch is configured to run the the compass task whenever a .scss file is updated. The compass task is configured to compile the Sass files specified in the sassDir property (src/sass/) and output to the cssDir specified (build/css/).

CLI / Terminal output from changed Sass file.

>> File "src/sass/reset.scss" changed.

Running "compass:dev" (compass) task
overwrite build/css/reset.css (0.02s)
unchanged src/sass/style.scss
Compilation took 0.053s

Done, without errors.
Completed in 0.717s at Sat Nov 23 2013 17:14:57 GMT-0500 (EST) - Waiting...
Source Code
December 2014 — New Page added to cover using a static web server with live browser reloading.

HTML 5 Template

Template with html5.js shiv *
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My Super Site!</title>
  <meta name="description" content="My Super Site!">
  <meta name="author" content="My Name">

  <link rel="stylesheet" href="css/styles.css">

  <!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
</head>
<body>

</body>
</html>

* Inspired by HTML5 Boilerplate

Emmet

If the Emmet plugin is installed in your code editor, you can use the ! alias or html:5 abbreviation then tab to stub out the template.


Easy Browsersync Server

Easy Browsersync Server is an HTML 5 Template that comes with a NPM package config to install a minimal set of development tools including a Browsersync server and Gulp task runner. After installation, a simple gulp server command loads the html 5 template in a browser using Browsersync. Any edits made to the html or sass (scss) files are processed instantly and reloaded into the browser.

source code

  1. Requires Node.js

  2. Download or clone this repsoitory.

  3. Change directory to /uiCookbook/easybs

  4. Run npm install from a bash terminal or command prompt. This will read the package.json file and install the dependencies into the easybs project.

$ npm install
  • Finally, run gulp server to load the index.html file in a web browser
$ gulp server

If you wish to include normalize.scss in your sass build, run this task:

$ gulp cp

Then uncomment the normalize import statement at the top of /src/sass/base/_base.scss

Additional reading:


Easy Web Server

If you don’t need all the overhead of the Browsersync server, this Gulp webserver plugin with LiveReload is a good alternative. The uiCookbook – gulp-webserver branch contains an example to get you started.

source code

Or static http-server that can run from any project folder, npm install -g http-server

CSS 3

CSS 3 includes all of the CSS 1 and CSS 2.1 properties, plus the new properties listed below. CSS 1 properties are listed on the CSS 1 page and the CSS 2.1 properties are listed on the CSS 2.1 page. Also listed on this page, are the CSS 3 Selectors.

CSS 3 Selectors

Coming soon …

CSS 2.1

CSS 2.1 includes all of the CSS 1 properties plus the CSS 2.1 properties listed below. CSS 1 properties are listed on the CSS 1 page. CSS 3 properties are listed on the CSS 3 page. Also listed on this page, are the CSS 2 Selectors.

CSS 2 Selectors

Coming soon …

CSS 1

CSS 1 properties listed below. CSS 2 properties are listed on the CSS 2 page. CSS 3 properties are listed on the CSS 3 page. Also listed on this page, are the CSS 1 Selectors.

CSS 1 Selectors

Coming soon …

DotNetNuke CSS and JS Module Development – Part One

During module development, to see all of the js and css files in firebug or your favorite client debugging tool of choice, turn off the file combination provider. In this section at or near the bottom of your web.config, set the provider enableCompositeFiles attributes from true to false as shown in the example below.

<clientDependency version="2" fileDependencyExtensions=".js,.css">
  <fileRegistration defaultProvider="LoaderControlProvider">
    <providers>
      <add name="DnnBodyProvider" type="DotNetNuke.Web.Client.Providers.DnnBodyProvider, DotNetNuke.Web.Client" enableCompositeFiles="false" />
      <add name="DnnFormBottomProvider" type="DotNetNuke.Web.Client.Providers.DnnFormBottomProvider, DotNetNuke.Web.Client" enableCompositeFiles="false" />
      <add name="PageHeaderProvider" type="ClientDependency.Core.FileRegistration.Providers.PageHeaderProvider, ClientDependency.Core" enableCompositeFiles="false" />
      <add name="LazyLoadProvider" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadProvider, ClientDependency.Core" enableCompositeFiles="false" />
      <add name="LoaderControlProvider" type="ClientDependency.Core.FileRegistration.Providers.LoaderControlProvider, ClientDependency.Core" enableCompositeFiles="false" />
      <add name="DnnPageHeaderProvider" type="DotNetNuke.Web.Client.Providers.DnnPageHeaderProvider, DotNetNuke.Web.Client" enableCompositeFiles="false" />
    </providers>
  </fileRegistration>
  <compositeFiles defaultFileProcessingProvider="CompositeFileProcessor" compositeFileHandlerPath="~/DependencyHandler.axd">
    <fileProcessingProviders>
      <add name="CompositeFileProcessor" type="ClientDependency.Core.CompositeFiles.Providers.CompositeFileProcessingProvider, ClientDependency.Core" enableCssMinify="false" enableJsMinify="true" persistFiles="true" compositeFilePath="~/App_Data/ClientDependency" bundleDomains="" urlType="MappedId" />
    </fileProcessingProviders>
  </compositeFiles>
</clientDependency>

Here is another web.config change to speed up the page load after a new build.

Change

<compilation debug="true" strict="false">

To

<compilation debug="true" strict="false" optimizeCompilations="true">

Resources

Random full page background

This Tutorial is written with Drupal 7 in mind. However, it can be applied to any website.

While upgrading and redesigning thebga.org golf association website, I decided to figure out how to have a random full page background part of the design. Drupal 7 makes it easy to include js and keep it, the theme and templates all separate from the Drupal core. The key is separation of your theme and it’s modules from the Drupal core and it’s modules. The Zen theme and Starter Kit make this very easy to accomplish.

Create or add this code to a javascript file in your themes “js” folder. I saved the file as random-bg.js (/sites/all/themes/thebga/js/random-bg.js).

(function ($) {
    $(document).ready(function() {
	var bgimages = [
	    'ovl_2010_wellman_rw.jpg',
	    'ovl_2010_wellman_sunday_am.jpg',
	    'ovl_2010_wellman_tobaccoroad_01.jpg',
	    'ovl_2010_wellman_tobaccoroad_14.jpg',
	    'ovl_2011_bridges_15.jpg',
	    'ovl_2011_dos-equis_sunday.jpg',
	    'ovl_2011_spam_friday01.jpg',
	    'ovl_2011_spam_friday02.jpg',
	    'ovl_2011_spam_friday03.jpg'
	];
	$('body').css({'background-image': 'url(sites/all/themes/thebga/images/bg-body/' + bgimages[Math.floor(Math.random() * bgimages.length)] + ')'});
    });
})(jQuery);

Note the JavaScript closure around

$(document).ready(function()

more info on that here: drupal.org/node/171213.

Put your background images in /sites/all/themes/thebga/images/bg-body/. The bg-body directory is optional, I created it to keep the background images separate from the other images used in the theme.

Add this code to the page-backgrounds.css (/sites/all/themes/thebga/css/page-backgrounds.css).

body {
    /* background color + default image (in-case random-bg.js fails) */
    background: #003c00 url('../images/bg-body/ovl_2011_dos-equis_sunday.jpg') no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}

Open the theme .info file and after

; Optionally add some JavaScripts to your theme.

add this line to load your javascript file:

scripts[] = js/random-bg.js

That is it! Every time the page is refreshed, a random background is loaded using a jQuery css modifier.

CSS

Resources