diff --git a/.csslintrc b/.csslintrc
index 46d6b60..3e2af48 100644
--- a/.csslintrc
+++ b/.csslintrc
@@ -1,5 +1,6 @@
{
"box-sizing" : false,
"display-property-grouping": false,
- "star-property-hack" : false
+ "star-property-hack" : false,
+ "unqualified-attributes" : false
}
diff --git a/.travis.yml b/.travis.yml
index 57642bf..6e5919d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,3 @@
language: node_js
node_js:
- "0.10"
-before_script:
- - npm install -g grunt-cli
-script: grunt test
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9c39ada..4a8f46b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -47,7 +47,7 @@ Building Pure is easy, run `grunt`:
$ grunt
```
-Pure use [CSSLint][] for basic testing to make sure we're shipping valid CSS
+Pure uses [CSSLint][] for basic testing to make sure we're shipping valid CSS
which complies with standard best practices. To run Pure's tests, run
`grunt test`:
diff --git a/Gruntfile.js b/Gruntfile.js
index 7277ea1..b33416d 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,71 +1,45 @@
-var path = require('path');
-
module.exports = function (grunt) {
// -- Config -------------------------------------------------------------------
grunt.initConfig({
- pkg : grunt.file.readJSON('package.json'),
- normalize: grunt.file.readJSON('src/base/bower.json'),
+ pkg : grunt.file.readJSON('package.json'),
+ bower: grunt.file.readJSON('bower.json'),
- // -- Constants ------------------------------------------------------------
+ // -- bower.json Config ---------------------------------------------------------
- BUILD_COMMENT: 'THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT!',
+ bower_json: {
+ release: {
+ values: {
+ main: 'pure.css'
+ },
+
+ dest: 'build/'
+ }
+ },
// -- Clean Config ---------------------------------------------------------
clean: {
build : ['build/'],
build_res: ['build/*-r.css'],
- release : ['release/<%= pkg.version %>/'],
- base : ['src/base/css/', 'src/base/bower.json', 'src/base/LICENSE.md']
+ release : ['release/<%= pkg.version %>/']
},
// -- Copy Config ----------------------------------------------------------
copy: {
build: {
- expand : true,
- flatten: true,
src : 'src/**/css/*.css',
dest : 'build/',
-
- rename: function (dest, src) {
- // normalize -> base
- src = src.replace(/^normalize(-.+\.css|\.css)$/, 'base$1');
- return path.join(dest, src);
- }
+ expand : true,
+ flatten: true
},
- normalize: {
- expand : true,
- flatten: true,
- cwd : 'bower_components/normalize-css/',
- src : '{bower.json,LICENSE.md,normalize.css}',
- dest : 'src/base/',
-
- rename: function (dest, file) {
- if (grunt.file.isMatch('*.css', file)) {
- return path.join(dest, 'css', file);
- }
-
- return path.join(dest, file);
- },
-
- options: {
- processContent: function (content, file) {
- var comment = grunt.config('BUILD_COMMENT');
-
- if (grunt.file.isMatch({matchBase: true}, '*.css', file)) {
- content = '/* ' + comment + ' */\n' + content;
- } else if (grunt.file.isMatch({matchBase: true}, '*.html', file)) {
- content = '\n' + content;
- }
-
- return content;
- }
- }
+ release: {
+ src : '{LICENSE.md,README.md,HISTORY.md}',
+ dest: 'build/'
}
},
@@ -74,13 +48,17 @@ grunt.initConfig({
concat: {
build: {
files: [
+ {'build/base.css': [
+ 'bower_components/normalize-css/normalize.css',
+ 'build/base.css'
+ ]},
+
{'build/buttons.css': [
'build/buttons-core.css',
'build/buttons.css'
]},
{'build/forms-nr.css': [
- 'build/forms-core.css',
'build/forms.css'
]},
@@ -89,16 +67,11 @@ grunt.initConfig({
'build/forms-r.css'
]},
- {'build/grids-nr.css': [
+ {'build/grids.css': [
'build/grids-core.css',
'build/grids-units.css'
]},
- {'build/grids.css': [
- 'build/grids-nr.css',
- 'build/grids-r.css'
- ]},
-
{'build/menus-nr.css': [
'build/menus-core.css',
'build/menus.css',
@@ -108,30 +81,28 @@ grunt.initConfig({
{'build/menus.css': [
'build/menus-nr.css',
'build/menus-r.css'
+ ]},
+
+ // Rollups
+
+ {'build/<%= pkg.name %>.css': [
+ 'build/base.css',
+ 'build/grids.css',
+ 'build/buttons.css',
+ 'build/forms.css',
+ 'build/menus.css',
+ 'build/tables.css'
+ ]},
+
+ {'build/<%= pkg.name %>-nr.css': [
+ 'build/base.css',
+ 'build/grids.css',
+ 'build/buttons.css',
+ 'build/forms-nr.css',
+ 'build/menus-nr.css',
+ 'build/tables.css'
]}
]
- },
-
- all: {
- files: {
- 'build/<%= pkg.name %>-min.css': [
- 'build/base-min.css',
- 'build/buttons-min.css',
- 'build/forms-min.css',
- 'build/grids-min.css',
- 'build/menus-min.css',
- 'build/tables-min.css'
- ],
-
- 'build/<%= pkg.name %>-nr-min.css': [
- 'build/base-min.css',
- 'build/buttons-min.css',
- 'build/forms-nr-min.css',
- 'build/grids-nr-min.css',
- 'build/menus-nr-min.css',
- 'build/tables-min.css'
- ]
- }
}
},
@@ -142,20 +113,19 @@ grunt.initConfig({
csslintrc: '.csslintrc'
},
- src: {
- src: [
- 'src/**/css/*.css',
- '!src/base/css/*',
- '!src/forms/css/forms-core.css'
- ]
- }
+ base : ['src/base/css/*.css'],
+ buttons: ['src/buttons/css/*.css'],
+ forms : ['src/forms/css/*.css'],
+ grids : ['src/grids/css/*.css'],
+ menus : ['src/menus/css/*.css'],
+ tables : ['src/tables/css/*.css']
},
// -- CSSMin Config --------------------------------------------------------
cssmin: {
options: {
- // report: 'gzip'
+ noAdvanced: true
},
files: {
@@ -170,12 +140,12 @@ grunt.initConfig({
compress: {
release: {
options: {
- archive: 'release/<%= pkg.version %>/<%= pkg.name %>-<%= pkg.version %>.zip'
+ archive: 'release/<%= pkg.version %>/<%= pkg.name %>-<%= pkg.version %>.tar.gz'
},
expand : true,
flatten: true,
- src : 'build/*.css',
+ src : 'build/*',
dest : '<%= pkg.name %>/<%= pkg.version %>/'
}
},
@@ -187,7 +157,7 @@ grunt.initConfig({
options: {
banner: [
'/*!',
- 'normalize.css v<%= normalize.version %> | MIT License | git.io/normalize',
+ 'normalize.css v<%= bower.devDependencies["normalize-css"] %> | MIT License | git.io/normalize',
'Copyright (c) Nicolas Gallagher and Jonathan Neal',
'*/\n'
].join('\n')
@@ -195,7 +165,7 @@ grunt.initConfig({
expand: true,
cwd : 'build/',
- src : ['base*.css', 'forms*.css', 'tables*.css', '<%= pkg.name %>*.css']
+ src : ['base*.css', '<%= pkg.name %>*.css']
},
yahoo: {
@@ -203,7 +173,7 @@ grunt.initConfig({
banner: [
'/*!',
'Pure v<%= pkg.version %>',
- 'Copyright 2013 Yahoo! Inc. All rights reserved.',
+ 'Copyright 2014 Yahoo! Inc. All rights reserved.',
'Licensed under the BSD License.',
'https://github.com/yui/pure/blob/master/LICENSE.md',
'*/\n'
@@ -215,16 +185,52 @@ grunt.initConfig({
}
},
- // -- Contextualize Config -------------------------------------------------
+ // -- Pure Grids Units Config ----------------------------------------------
- contextualize: {
- normalize: {
- src : 'src/base/css/normalize.css',
- dest: 'src/base/css/normalize-context.css',
+ pure_grids: {
+ default_units: {
+ dest: 'build/grids-units.css',
options: {
- prefix: '.pure',
- banner: '/* <%= BUILD_COMMENT %> */\n'
+ units: [5, 24]
+ }
+ },
+
+ responsive: {
+ dest: 'build/grids-responsive.css',
+
+ options: {
+ mediaQueries: {
+ sm: 'screen and (min-width: 35.5em)', // 568px
+ md: 'screen and (min-width: 48em)', // 768px
+ lg: 'screen and (min-width: 64em)', // 1024px
+ xl: 'screen and (min-width: 80em)' // 1280px
+ }
+ }
+ }
+ },
+
+ // -- Strip Media Queries Config -------------------------------------------
+
+ stripmq: {
+ all: {
+ files: {
+ //follows the pattern 'destination': ['source']
+ 'build/grids-responsive-old-ie.css':
+ ['build/grids-responsive.css']
+ }
+ }
+ },
+
+ // -- CSS Selectors Config -------------------------------------------------
+
+ css_selectors: {
+ base: {
+ src : 'build/base.css',
+ dest: 'build/base-context.css',
+
+ options: {
+ mutations: [{prefix: '.pure'}]
}
}
},
@@ -234,7 +240,7 @@ grunt.initConfig({
observe: {
src: {
files: 'src/**/css/*.css',
- tasks: ['test', 'suppress', 'default'],
+ tasks: ['test', 'suppress', 'build'],
options: {
interrupt: true
@@ -245,6 +251,7 @@ grunt.initConfig({
// -- Main Tasks ---------------------------------------------------------------
+// npm tasks.
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-concat');
@@ -252,169 +259,38 @@ grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-contrib-watch');
+grunt.loadNpmTasks('grunt-css-selectors');
+grunt.loadNpmTasks('grunt-pure-grids');
+grunt.loadNpmTasks('grunt-stripmq');
-grunt.registerTask('default', [
+// Local tasks.
+grunt.loadTasks('tasks/');
+
+grunt.registerTask('default', ['import', 'test', 'build']);
+grunt.registerTask('import', ['bower_install']);
+grunt.registerTask('test', ['csslint']);
+grunt.registerTask('build', [
'clean:build',
'copy:build',
+ 'pure_grids',
+ 'stripmq',
'concat:build',
'clean:build_res',
+ 'css_selectors:base',
'cssmin',
- 'concat:all',
'license'
]);
-grunt.registerTask('test', [
- 'csslint'
-]);
-
// Makes the `watch` task run a build first.
grunt.renameTask('watch', 'observe');
grunt.registerTask('watch', ['default', 'observe']);
-grunt.registerTask('import', [
- 'bower-install',
- 'import-normalize'
-]);
-
grunt.registerTask('release', [
- 'test',
'default',
'clean:release',
+ 'copy:release',
+ 'bower_json:release',
'compress:release'
]);
-// -- Suppress Task ------------------------------------------------------------
-
-grunt.registerTask('suppress', function () {
- var allowed = ['success', 'fail', 'warn', 'error'];
-
- grunt.util.hooker.hook(grunt.log, {
- passName: true,
-
- pre: function (name) {
- if (allowed.indexOf(name) === -1) {
- grunt.log.muted = true;
- }
- },
-
- post: function () {
- grunt.log.muted = false;
- }
- });
-});
-
-// -- Import Tasks -------------------------------------------------------------
-
-grunt.registerTask('import-normalize', [
- 'clean:base',
- 'copy:normalize',
- 'contextualize:normalize'
-]);
-
-// -- Bower Task ---------------------------------------------------------------
-
-grunt.registerTask('bower-install', 'Installs Bower dependencies.', function () {
- var bower = require('bower'),
- done = this.async();
-
- bower.commands.install()
- .on('data', function (data) { grunt.log.write(data); })
- .on('end', done);
-});
-
-// -- License Task -------------------------------------------------------------
-
-grunt.registerMultiTask('license', 'Stamps license banners on files.', function () {
- var options = this.options({banner: ''}),
- banner = grunt.template.process(options.banner),
- tally = 0;
-
- this.files.forEach(function (filePair) {
- filePair.src.forEach(function (file) {
- grunt.file.write(file, banner + grunt.file.read(file));
- tally += 1;
- });
- });
-
- grunt.log.writeln('Stamped license on ' + String(tally).cyan + ' files.');
-});
-
-// -- Contextualize Task -------------------------------------------------------
-
-grunt.registerMultiTask('contextualize', 'Makes Contextualized CSS files.', function () {
- var Parser = require('parserlib').css.Parser,
- done = this.async(),
- options = this.options({banner: ''}),
- banner = grunt.template.process(options.banner),
- processing = 0;
-
- function oneDone() {
- if (!(processing -= 1)) {
- done();
- }
- }
-
- this.files.forEach(function (filePair) {
- filePair.src.forEach(function (file) {
- var src = grunt.file.read(file),
- contextual = banner,
- parser = new Parser();
-
- parser.addListener('endstylesheet', function () {
- grunt.file.write(filePair.dest, contextual);
- grunt.log.writeln('File "' + filePair.dest + '" created.');
- oneDone();
- });
-
- // Fired right before CSS properties are parsed for a certain rule.
- // Go through and add all the selectors to the `css` string.
- parser.addListener('startrule', function (event) {
- var prefix = options.prefix;
-
- event.selectors.forEach(function (selector, i) {
- var nextSelector = event.selectors[i + 1];
-
- // If the selector does not contain the html selector, we
- // can go ahead and prepend `prefix` in front of it.
- if (selector.text.indexOf('html') === -1) {
- contextual += prefix + ' ' + selector.text;
- } else if (selector.text.indexOf('html') !== -1) {
- // If it contains `html`, replace the `html` with the
- // `prefix`. Replace multiple spaces with a single
- // space. This is for the case where
- // `html input[type='button']` comes through as
- // `html input[type='button']`.
- contextual += selector.text.replace('html', prefix).replace(/ +/g, ' ');
- }
-
- // If theres another selector, add a comma.
- if (nextSelector) {
- contextual += ',\n';
- } else {
- // Otherwise, add an opening bracket for properties
- contextual += ' {\n';
- }
- });
- });
-
- // Fired right after CSS properties are parsed for a certain rule.
- // Add the closing bracket to end the CSS Rule.
- parser.addListener('endrule', function (event) {
- contextual += '}\n';
- });
-
- // Fired for each property that the parser encounters. Add these
- // properties to the `css` string with 4 spaces.
- parser.addListener('property', function (event) {
- // Add 4 spaces tab.
- contextual += ' ' + event.property + ': ' + event.value + ';\n';
- });
-
- // Do the parsing.
- processing += 1;
- parser.parse(src);
- });
- });
-});
-
};
diff --git a/HISTORY.md b/HISTORY.md
index a373b45..445de01 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,10 +1,243 @@
Pure Change History
===================
-NEXT
-----
+0.5.0 (2014-05-27)
+------------------
+
+### Base
+
+* Added the `.pure-img` class name for make images scale with the viewport in
+ fluid layouts.
+
+### Grids
+
+* __[!]__ Removed `.pure-g-r` from core, in favor of a mobile-first responsive
+ grid system. ([#24][], [#267][])
+
+ To use the mobile-first grid system, you need to pull in `pure.css`, along
+ with `grids-responsive.css`. We also have `grids-responsive-old-ie.css` that
+ you can serve to IE < 9 users so that they can view a desktop-version of your
+ website:
+
+ ```html
+
+
+
+
+
+
+ ```
+
+ Find out more about the new grid system at