├── .gitignore ├── grunt ├── Gruntfile.js ├── dev │ └── main.css ├── package.json └── prod │ └── main.css ├── gulp ├── dev │ └── main.css ├── gulpfile.js ├── package.json └── prod │ └── main.css └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /grunt/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | var processors = [ 4 | require('autoprefixer')({ browsers: ['last 2 versions', 'Firefox > 20'] }), 5 | require('cssnext')(), 6 | require('precss')(), 7 | require('postcss-quantity-queries')(), 8 | require('postcss-short')() 9 | ]; 10 | 11 | grunt.initConfig({ 12 | pkg: grunt.file.readJSON('package.json'), 13 | postcss: { 14 | options: { 15 | processors: processors 16 | }, 17 | dist: { 18 | files: [{ 19 | expand: true, 20 | cwd: 'dev/', 21 | src: ['**/*.css'], 22 | dest: 'prod/' 23 | }] 24 | } 25 | } 26 | }); 27 | 28 | // Load post-css. 29 | grunt.loadNpmTasks('grunt-postcss'); 30 | 31 | grunt.registerTask('default', ['postcss']); 32 | 33 | }; -------------------------------------------------------------------------------- /grunt/dev/main.css: -------------------------------------------------------------------------------- 1 | /*==================================== 2 | = AutoPrefixer = 3 | ====================================*/ 4 | .item { 5 | display: flex; 6 | flex-flow: row wrap; 7 | } 8 | 9 | /*=============================== 10 | = CSSNext = 11 | ===============================*/ 12 | 13 | /*========== Native Variables ==========*/ 14 | :root { 15 | --linkColour: purple; 16 | } 17 | 18 | a { 19 | color: var(--linkColour); 20 | } 21 | 22 | /*========== Custom Media Queries with Ranges ==========*/ 23 | 24 | @custom-media --only-medium-screen (width >= 500px) and (width <= 1200px); 25 | 26 | @media (--only-medium-screen) { 27 | body { 28 | background: rebeccapurple; 29 | } 30 | } 31 | 32 | /*========== Custom Selectors ==========*/ 33 | @custom-selector :--enter :hover, :focus; 34 | @custom-selector :--input input, .input, .inputField; 35 | 36 | a:--enter { 37 | text-decoration: none; 38 | } 39 | 40 | :--input { 41 | border: 0; 42 | } 43 | 44 | /*============================== 45 | = PreCSS = 46 | ==============================*/ 47 | 48 | /*========== Variables ==========*/ 49 | $blue: #0000ff; 50 | $green: #00ff00; 51 | $radius: 10px; 52 | 53 | .square { 54 | background: $blue; 55 | border-radius: $radius; 56 | } 57 | 58 | /*========== Creating a mixin ==========*/ 59 | @define-mixin square $dimension { 60 | width: $dimension; 61 | height: $dimension; 62 | } 63 | 64 | /*========== Nesting, Variables and Mixins ==========*/ 65 | .button { 66 | @mixin square 200px; 67 | background: $green; 68 | &:hover { 69 | background: $blue; 70 | } 71 | } 72 | 73 | 74 | /*======================================== 75 | = Quantity Queries = 76 | ========================================*/ 77 | 78 | .container > .item:at-least(5) { 79 | background: blue; 80 | } 81 | 82 | .item > a:at-most(10) { 83 | color: green; 84 | } 85 | 86 | .gallery > img:between(4, 7) { 87 | width: 25%; 88 | } 89 | 90 | .profiles:exactly(4) { 91 | flex: 1 0 50%; 92 | } 93 | 94 | /*===================================== 95 | = PostCSS-Short = 96 | =====================================*/ 97 | 98 | /*========== Text ==========*/ 99 | p { 100 | text: 300 uppercase dimgrey center 16px 1.7 .05em; 101 | } 102 | 103 | /*========== Position ==========*/ 104 | section { 105 | position: absolute 10px * *; 106 | } 107 | 108 | .topNav { 109 | position: fixed 0 * * 0; 110 | } 111 | 112 | .modal { 113 | position: fixed 40% 25%; 114 | } 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /grunt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-grunt-example", 3 | "version": "1.0.0", 4 | "description": "PostCSS example for Smashing Magazine by Drew Minns", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "http://github.com/drewminns" 12 | }, 13 | "author": "Drew Minns", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "autoprefixer": "^6.1.2", 17 | "cssnext": "^1.8.3", 18 | "grunt": "^0.4.5", 19 | "grunt-postcss": "^0.5.5", 20 | "postcss-quantity-queries": "^0.3.1", 21 | "postcss-short": "^0.3.0", 22 | "precss": "^0.3.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /grunt/prod/main.css: -------------------------------------------------------------------------------- 1 | /*==================================== 2 | = AutoPrefixer = 3 | ====================================*/ 4 | .item { 5 | display: -webkit-flex; 6 | display: -ms-flexbox; 7 | display: -moz-box; 8 | display: -webkit-box; 9 | display: flex; 10 | -webkit-flex-flow: row wrap; 11 | -ms-flex-flow: row wrap; 12 | flex-flow: row wrap; 13 | } 14 | 15 | /*=============================== 16 | = CSSNext = 17 | ===============================*/ 18 | 19 | /*========== Native Variables ==========*/ 20 | 21 | a { 22 | color: purple; 23 | } 24 | 25 | /*========== Custom Media Queries with Ranges ==========*/ 26 | 27 | @media (min-width: 500px) and (max-width: 1200px) { 28 | body { 29 | background: rgb(102, 51, 153); 30 | } 31 | } 32 | 33 | /*========== Custom Selectors ==========*/ 34 | 35 | a:hover, 36 | a:focus { 37 | text-decoration: none; 38 | } 39 | 40 | input, 41 | .input, 42 | .inputField { 43 | border: 0; 44 | } 45 | 46 | /*============================== 47 | = PreCSS = 48 | ==============================*/ 49 | 50 | /*========== Variables ==========*/ 51 | 52 | .square { 53 | background: #0000ff; 54 | border-radius: 10px; 55 | } 56 | 57 | /*========== Creating a mixin ==========*/ 58 | 59 | /*========== Nesting, Variables and Mixins ==========*/ 60 | .button { 61 | width: 200px; 62 | height: 200px; 63 | background: #00ff00; 64 | } 65 | .button:hover { 66 | background: #0000ff; 67 | } 68 | 69 | 70 | /*======================================== 71 | = Quantity Queries = 72 | ========================================*/ 73 | 74 | .container > .item:nth-last-child(n+5), .container > .item:nth-last-child(n+5) ~ .item { 75 | background: blue; 76 | } 77 | 78 | .item > a:nth-last-child(-n+10):first-child, .item > a:nth-last-child(-n+10):first-child ~ a { 79 | color: green; 80 | } 81 | 82 | .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child, .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child ~ img { 83 | width: 25%; 84 | } 85 | 86 | .profiles:nth-last-child(4):first-child, .profiles:nth-last-child(4):first-child ~ .profiles { 87 | -webkit-flex: 1 0 50%; 88 | -ms-flex: 1 0 50%; 89 | -webkit-box-flex: 1; 90 | flex: 1 0 50%; 91 | } 92 | 93 | /*===================================== 94 | = PostCSS-Short = 95 | =====================================*/ 96 | 97 | /*========== Text ==========*/ 98 | p { 99 | color: dimgrey; 100 | font-weight: 300; 101 | text-align: center; 102 | text-transform: uppercase; 103 | font-size: 16px; 104 | line-height: 1.7; 105 | letter-spacing: .05em; 106 | } 107 | 108 | /*========== Position ==========*/ 109 | section { 110 | position: absolute; 111 | top: 10px; 112 | } 113 | 114 | .topNav { 115 | position: fixed; 116 | top: 0; 117 | left: 0; 118 | } 119 | 120 | .modal { 121 | position: fixed; 122 | top: 40%; 123 | right: 25%; 124 | bottom: 40%; 125 | left: 25%; 126 | } 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /gulp/dev/main.css: -------------------------------------------------------------------------------- 1 | /*==================================== 2 | = AutoPrefixer = 3 | ====================================*/ 4 | .item { 5 | display: flex; 6 | flex-flow: row wrap; 7 | } 8 | 9 | /*=============================== 10 | = CSSNext = 11 | ===============================*/ 12 | 13 | /*========== Native Variables ==========*/ 14 | :root { 15 | --linkColour: purple; 16 | } 17 | 18 | a { 19 | color: var(--linkColour); 20 | } 21 | 22 | /*========== Custom Media Queries with Ranges ==========*/ 23 | 24 | @custom-media --only-medium-screen (width >= 500px) and (width <= 1200px); 25 | 26 | @media (--only-medium-screen) { 27 | body { 28 | background: rebeccapurple; 29 | } 30 | } 31 | 32 | /*========== Custom Selectors ==========*/ 33 | @custom-selector :--enter :hover, :focus; 34 | @custom-selector :--input input, .input, .inputField; 35 | 36 | a:--enter { 37 | text-decoration: none; 38 | } 39 | 40 | :--input { 41 | border: 0; 42 | } 43 | 44 | /*============================== 45 | = PreCSS = 46 | ==============================*/ 47 | 48 | /*========== Variables ==========*/ 49 | $blue: #0000ff; 50 | $green: #00ff00; 51 | $radius: 10px; 52 | 53 | .square { 54 | background: $blue; 55 | border-radius: $radius; 56 | } 57 | 58 | /*========== Creating a mixin ==========*/ 59 | @define-mixin square $dimension { 60 | width: $dimension; 61 | height: $dimension; 62 | } 63 | 64 | /*========== Nesting, Variables and Mixins ==========*/ 65 | .button { 66 | @mixin square 200px; 67 | background: $green; 68 | &:hover { 69 | background: $blue; 70 | } 71 | } 72 | 73 | 74 | /*======================================== 75 | = Quantity Queries = 76 | ========================================*/ 77 | 78 | .container > .item:at-least(5) { 79 | background: blue; 80 | } 81 | 82 | .item > a:at-most(10) { 83 | color: green; 84 | } 85 | 86 | .gallery > img:between(4, 7) { 87 | width: 25%; 88 | } 89 | 90 | .profiles:exactly(4) { 91 | flex: 1 0 50%; 92 | } 93 | 94 | /*===================================== 95 | = PostCSS-Short = 96 | =====================================*/ 97 | 98 | /*========== Text ==========*/ 99 | p { 100 | text: 300 uppercase dimgrey center 16px 1.7 .05em; 101 | } 102 | 103 | /*========== Position ==========*/ 104 | section { 105 | position: absolute 10px * *; 106 | } 107 | 108 | .topNav { 109 | position: fixed 0 * * 0; 110 | } 111 | 112 | .modal { 113 | position: fixed 40% 25%; 114 | } 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /gulp/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | postcss = require('gulp-postcss'); 3 | 4 | // Array to store PostCSS plugins 5 | var processors = [ 6 | require('autoprefixer')({ browsers: ['last 2 versions', 'Firefox > 20'] }), 7 | require('cssnext')(), 8 | require('precss')(), 9 | require('postcss-quantity-queries')(), 10 | require('postcss-short')() 11 | ]; 12 | 13 | // 'styles' task used to transform CSS 14 | gulp.task('styles', function() { 15 | return gulp.src('dev/main.css') 16 | // Pipe the styles in through PostCSS and pass in the 'processors' array. 17 | .pipe(postcss(processors)) 18 | // Output the transformed CSS to the 19 | .pipe(gulp.dest('prod')); 20 | }); -------------------------------------------------------------------------------- /gulp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-gulp-example", 3 | "version": "1.0.0", 4 | "description": "PostCSS example for Smashing Magazine by Drew Minns", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "http://github.com/drewminns" 12 | }, 13 | "author": "Drew Minns", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "autoprefixer": "^6.1.2", 17 | "cssnext": "^1.8.3", 18 | "gulp": "^3.9.0", 19 | "gulp-postcss": "^6.0.1", 20 | "postcss-quantity-queries": "^0.3.1", 21 | "postcss-short": "^0.3.0", 22 | "precss": "^0.3.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gulp/prod/main.css: -------------------------------------------------------------------------------- 1 | /*==================================== 2 | = AutoPrefixer = 3 | ====================================*/ 4 | .item { 5 | display: -webkit-flex; 6 | display: -ms-flexbox; 7 | display: -moz-box; 8 | display: -webkit-box; 9 | display: flex; 10 | -webkit-flex-flow: row wrap; 11 | -ms-flex-flow: row wrap; 12 | flex-flow: row wrap; 13 | } 14 | 15 | /*=============================== 16 | = CSSNext = 17 | ===============================*/ 18 | 19 | /*========== Native Variables ==========*/ 20 | 21 | a { 22 | color: purple; 23 | } 24 | 25 | /*========== Custom Media Queries with Ranges ==========*/ 26 | 27 | @media (min-width: 500px) and (max-width: 1200px) { 28 | body { 29 | background: rgb(102, 51, 153); 30 | } 31 | } 32 | 33 | /*========== Custom Selectors ==========*/ 34 | 35 | a:hover, 36 | a:focus { 37 | text-decoration: none; 38 | } 39 | 40 | input, 41 | .input, 42 | .inputField { 43 | border: 0; 44 | } 45 | 46 | /*============================== 47 | = PreCSS = 48 | ==============================*/ 49 | 50 | /*========== Variables ==========*/ 51 | 52 | .square { 53 | background: #0000ff; 54 | border-radius: 10px; 55 | } 56 | 57 | /*========== Creating a mixin ==========*/ 58 | 59 | /*========== Nesting, Variables and Mixins ==========*/ 60 | .button { 61 | width: 200px; 62 | height: 200px; 63 | background: #00ff00; 64 | } 65 | .button:hover { 66 | background: #0000ff; 67 | } 68 | 69 | 70 | /*======================================== 71 | = Quantity Queries = 72 | ========================================*/ 73 | 74 | .container > .item:nth-last-child(n+5), .container > .item:nth-last-child(n+5) ~ .item { 75 | background: blue; 76 | } 77 | 78 | .item > a:nth-last-child(-n+10):first-child, .item > a:nth-last-child(-n+10):first-child ~ a { 79 | color: green; 80 | } 81 | 82 | .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child, .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child ~ img { 83 | width: 25%; 84 | } 85 | 86 | .profiles:nth-last-child(4):first-child, .profiles:nth-last-child(4):first-child ~ .profiles { 87 | -webkit-flex: 1 0 50%; 88 | -ms-flex: 1 0 50%; 89 | -webkit-box-flex: 1; 90 | flex: 1 0 50%; 91 | } 92 | 93 | /*===================================== 94 | = PostCSS-Short = 95 | =====================================*/ 96 | 97 | /*========== Text ==========*/ 98 | p { 99 | color: dimgrey; 100 | font-weight: 300; 101 | text-align: center; 102 | text-transform: uppercase; 103 | font-size: 16px; 104 | line-height: 1.7; 105 | letter-spacing: .05em; 106 | } 107 | 108 | /*========== Position ==========*/ 109 | section { 110 | position: absolute; 111 | top: 10px; 112 | } 113 | 114 | .topNav { 115 | position: fixed; 116 | top: 0; 117 | left: 0; 118 | } 119 | 120 | .modal { 121 | position: fixed; 122 | top: 40%; 123 | right: 25%; 124 | bottom: 40%; 125 | left: 25%; 126 | } 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PostCSS Starter for Gulp and Grunt 2 | 3 | Within each task runner folder, run the following steps in the command line. 4 | 5 | * `npm install` - You may need to type `sudo` before the command and type in your password. 6 | * To run the gulp file, type `gulp styles`. 7 | * To run the grunt file, type `grunt`. 8 | 9 | Expand upon these tasks as you will! 10 | 11 | --------------------------------------------------------------------------------