├── .editorconfig ├── .eslintrc ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── dist └── minigrid.min.js ├── package.json ├── site ├── .gitignore ├── CNAME ├── README.md ├── build.js ├── index.html ├── index.md ├── logo.svg ├── normalize.css ├── package.json ├── styles.css └── template.hbs ├── src └── index.js └── tests └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/rules 2 | { 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "rules": { 8 | "strict": 0, 9 | "quotes": [2, "single"], 10 | "no-underscore-dangle": 0, 11 | "no-unused-expressions": 0, 12 | "new-cap": 0, 13 | "no-extra-boolean-cast": 0, 14 | "yoda": 0, 15 | "no-empty": 0, 16 | "no-use-before-define": 0, 17 | "camelcase": 0 18 | }, 19 | "globals": { 20 | "define": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *.log 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ### v3.1.1 4 | 5 | - Remove `overflow: hidden` https://github.com/henriquea/minigrid/issues/60 6 | 7 | ### v3.1.0 8 | 9 | - Add RTL support https://github.com/henriquea/minigrid/issues/59 10 | 11 | ### v3.0.6 12 | 13 | - Update `npmcdn` url https://github.com/henriquea/minigrid/pull/57 14 | 15 | ### v3.0.5 16 | 17 | - Revert breaking change https://github.com/henriquea/minigrid/issues/55 18 | 19 | ### v3.0.3 20 | 21 | - Add site to js.org 22 | 23 | ### v3.0.2 24 | 25 | - Move GitHub pages to `master` branch 26 | 27 | ### v3.0.1 28 | 29 | - Add dist file to `package.json` 30 | 31 | ### v3.0.0 32 | 33 | The major change is the API. We took one step back to its core principle of "keep it simple". 34 | 35 | ```js 36 | var props = { 37 | container: '.cards', 38 | item: '.card', 39 | guter: 8 40 | }; 41 | var grid = new Minigrid(props); 42 | grid.mount(); 43 | ``` 44 | 45 | - Back to 2kb 🎉 46 | - `mount()` method to initialize Minigrid 47 | - Animation was removed due to issues when dealing with many items which is the most of the user cases 48 | - Remove the custom loading causing issues when loaded with require 49 | - Round `posX`, `poxY` values #48 50 | - Fixes the issue when working with multiple grids/selectors #43 51 | - Works when loaded via module #40 52 | 53 | ### v2.2.0 54 | 55 | - Add containerLoaded and itemLoaded options #37 56 | - Fix minification #38 57 | - Remove webpack 58 | - Remove custom `forEach` loop 59 | - Replace custom `window.onload` function for `window.addEventListener('load')`. Closes #36 60 | - Add `backface-visibility` to prevent text rendering issues. Closes #26 61 | 62 | ### v2.1.3 63 | 64 | - Change default `gutter` to `0` 65 | - Fix issue uptading the container className with `--loaded` modifier multiple times 66 | 67 | ### v2.0.0 68 | 69 | The major change is that now minigrid receives a `props` object rather arguments. 70 | 71 | ```js 72 | // v1.x 73 | minigrid('.grid', '.grid-item'); 74 | 75 | // v2.0.0 76 | minigrid({ container: '.grid', item: '.grid-item'}); 77 | ``` 78 | 79 | On `window.onLoad` minigrid adds a new className, the container name plus the `--loaded` modifier. 80 | 81 | ```html 82 |
83 | ... 84 |
85 | ``` 86 | 87 | The same happens for each grid child item when it is ready for use. 88 | 89 | ```html 90 |
91 |
92 |
93 | ``` 94 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | **Be nice** 😎 2 | 3 | Bare in mind that minigrid's main concept is simplicity. The goal is to keep the API always at 2kb. Bug fixes are more than welcome! For any new feature please [submit an issue](https://github.com/henriquea/minigrid/issues) first before send any pull request. 4 | 5 | 🍺 6 | 7 | ## Tests 8 | 9 | All commits must pass the tests `npm run test`. 10 | 11 | Install browserify and testling globally. 12 | 13 | ```bash 14 | $ npm install 15 | $ npm install browserify -g 16 | $ npm install testling -g 17 | ``` 18 | 19 | ## Build 20 | 21 | The build task `npm run build` runs the tests and does the minification. 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Henrique Alves 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minigrid 2 | 3 | Minigrid is a minimal 2kb zero dependency cascading grid layout. 4 | 5 | Website & Documentation: [http://alves.im/minigrid](http://minigrid.js.org/). 6 | 7 | ## Demo 8 | 9 | There's a simple example on [jsbin](http://jsbin.com/wamele/2). 10 | 11 | ## Installation 12 | 13 | Using **NPM** 14 | 15 | ``` 16 | npm install minigrid --save 17 | ``` 18 | 19 | Or 1998 script tag from unpkg: 20 | 21 | ``` 22 | 23 | ``` 24 | 25 | ## Usage 26 | 27 | It works on a grid container with a group of grid items. 28 | ``` 29 |
30 |
31 |
32 |
33 |
34 | ``` 35 | 36 | Then: 37 | ``` 38 | var grid = new Minigrid({ 39 | container: '.cards', 40 | item: '.card', 41 | gutter: 6 42 | }); 43 | grid.mount(); 44 | ``` 45 | 46 | ### Limitation 47 | Minigrid was built having in mind "cards" with same width and different heights. If your cards have different width sizes or you need more power Minigrid might not be right for you. 48 | 49 | ## Contributing 50 | 51 | Plese see [CONTRIBUTING](CONTRIBUTING.md). 52 | 53 | ## License 54 | 55 | MIT © 2016 [Henrique Alves](http://twitter.com/healves82) 56 | -------------------------------------------------------------------------------- /dist/minigrid.min.js: -------------------------------------------------------------------------------- 1 | /* @license Minigrid v3.1.1 – minimal cascading grid layout http://alves.im/minigrid */ 2 | !function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.Minigrid=e()}(this,function(t){"use strict";function e(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}var i=function(t){var i=t.container instanceof Node?t.container:document.querySelector(t.container),r=t.item instanceof NodeList?t.item:i.querySelectorAll(t.item);this.props=e(t,{container:i,nodeList:r})};return i.prototype.mount=function(){if(!this.props.container)return!1;if(!this.props.nodeList||0===this.props.nodeList.length)return!1;var t="number"==typeof this.props.gutter&&isFinite(this.props.gutter)&&Math.floor(this.props.gutter)===this.props.gutter?this.props.gutter:0,e=this.props.done,i=this.props.container,r=this.props.nodeList;i.style.width="";var n=Array.prototype.forEach,o=i.getBoundingClientRect().width,s=r[0].getBoundingClientRect().width+t,p=Math.max(Math.floor((o-t)/s),1),a=0;o=s*p+t+"px",i.style.width=o,i.style.position="relative";for(var c=[],u=[],l=0;l (http://alves.im)", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/henriquea/minigrid/issues" 37 | }, 38 | "homepage": "http://alves.im/minigrid", 39 | "devDependencies": { 40 | "browserify": "^11.0.1", 41 | "eslint": "^1.4.3", 42 | "phantomjs": "1.9.2-6", 43 | "tape": "^4.0.2", 44 | "tape-run": "^1.1.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /site/CNAME: -------------------------------------------------------------------------------- 1 | minigrid.js.org 2 | -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | [minigrid.js.org](http://minigrid.js.org) 2 | -------------------------------------------------------------------------------- /site/build.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs'); 3 | var pkg = require('../package.json'); 4 | var markdownFile = fs.readFileSync('./index.md', 'utf8'); 5 | var templateFile = fs.readFileSync('./template.hbs', 'utf8'); 6 | 7 | var Handlebars = require('handlebars'); 8 | // 9 | function titleCase(str){ 10 | if (typeof str === 'undefined') return ''; 11 | return str.replace(/\w\S*/g, function(txt){ 12 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 13 | }); 14 | }; 15 | 16 | function extend(a, b) { 17 | for (var key in b) { 18 | if (b.hasOwnProperty(key)) { 19 | a[key] = b[key]; 20 | } 21 | } 22 | return a; 23 | } 24 | 25 | var markdownTemplate = Handlebars.compile(markdownFile); 26 | pkg.homepage = '[' + titleCase(pkg.name) + '](' + pkg.homepage + ')'; 27 | pkg.github = '[GitHub](' + pkg.repository.url + ')'; 28 | pkg.twitter = '['+ pkg.author.twitter + '](https://twitter.com/' + pkg.author.twitter + ')'; 29 | pkg.title = titleCase(pkg.name); 30 | pkg.keywords = pkg.keywords.join(','); 31 | var compiledMarkdown = markdownTemplate(pkg); 32 | 33 | var minify = require('html-minifier').minify; 34 | var remark = require('remark'); 35 | var html = require('remark-html'); 36 | var yamlConfig = require('remark-yaml-config'); 37 | var processor = remark().use(yamlConfig).use(html); 38 | var doc = processor.process([ 39 | '---', 40 | 'remark:', 41 | ' commonmark: true', 42 | '---', 43 | '', 44 | compiledMarkdown 45 | ].join('\n')); 46 | 47 | var data = { content: doc }; 48 | var options = extend(data, pkg); 49 | var template = Handlebars.compile(templateFile); 50 | var compiledTemplate = template(options); 51 | 52 | var html = minify(compiledTemplate, { 53 | collapseWhitespace: true 54 | }); 55 | 56 | fs.writeFileSync('index.html', html); 57 | -------------------------------------------------------------------------------- /site/index.html: -------------------------------------------------------------------------------- 1 | Minigrid

Minigrid

Minigrid

Minimal 2kb zero dependency cascading grid layout without pain.

Star

Demo

There's a simple example on jsbin.

Usage

It works on a grid container with a group of grid items.

<div class="cards">
 2 |   <div class="card"></div>
 3 |   <div class="card"></div>
 4 |   <div class="card"></div>
 5 | </div>
 6 | 

Then:

var grid = new Minigrid({
 7 |   container: '.cards',
 8 |   item: '.card',
 9 |   gutter: 6
10 | });
11 | grid.mount();
12 | 

Installation

Get it from npm.

npm install minigrid
13 | 

Or 1998 script tag from unpkg:

<script src="https://unpkg.com/minigrid@3.1.1/dist/minigrid.min.js"></script>
14 | 

Upgrade

Upgrading from v1.x or v2.x?

Please read the CHANGELOG for API changes.

Limitations

Minigrid was built having in mind "cards" with same width and different heights. If your cards have different width sizes or you need more power I would recommend Isotope.

Questions

Open an issue or hit me on Twitter.

-------------------------------------------------------------------------------- /site/index.md: -------------------------------------------------------------------------------- 1 | - [GitHub](https://github.com/henriquea/minigrid) 2 | - [npm](https://www.npmjs.com/package/minigrid) 3 | 4 | ![Minigrid](logo.svg) 5 | 6 | # Minigrid 7 | 8 | Minimal 2kb zero dependency cascading grid layout without pain. 9 | 10 |

Star

11 | 12 | ## Demo 13 | 14 | There's a simple example on [jsbin](http://jsbin.com/wamele/edit?js,output). 15 | 16 | ## Usage 17 | 18 | It works on a grid container with a group of grid items. 19 | 20 | ``` 21 |
22 |
23 |
24 |
25 |
26 | ``` 27 | 28 | Then: 29 | 30 | ``` 31 | var grid = new Minigrid({ 32 | container: '.cards', 33 | item: '.card', 34 | gutter: 6 35 | }); 36 | grid.mount(); 37 | ``` 38 | 39 | ## Installation 40 | 41 | Get it from npm. 42 | 43 | ``` 44 | npm install minigrid 45 | ``` 46 | 47 | Or 1998 script tag from [unpkg](https://unpkg.com/minigrid@{{version}}/dist/minigrid.min.js): 48 | 49 | ``` 50 | 51 | ``` 52 | 53 | ## Upgrade 54 | 55 | Upgrading from v1.x or v2.x? 56 | 57 | Please read the [CHANGELOG](https://github.com/henriquea/minigrid/blob/master/CHANGELOG.md) for API changes. 58 | 59 | ## Limitations 60 | 61 | Minigrid was built having in mind "cards" with same width and different heights. If your cards have different width sizes or you need more power I would recommend [Isotope](http://isotope.metafizzy.co/). 62 | 63 | ## Questions 64 | 65 | Open an [issue](https://github.com/henriquea/minigrid/issues) or hit me on Twitter. 66 | 67 | 68 | 69 | 70 | - [Minigrid](http://alves.im/minigrid) v{{version}} 71 | - [GitHub](https://github.com/henriquea/minigrid) 72 | - [npm](https://www.npmjs.com/package/minigrid) 73 | - 74 | -------------------------------------------------------------------------------- /site/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | minigrid-logo 5 | Created with Sketch Beta. 6 | 7 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /site/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Change the default font family in all browsers (opinionated). 5 | * 2. Prevent adjustments of font size after orientation changes in IE and iOS. 6 | */ 7 | 8 | html { 9 | font-family: sans-serif; /* 1 */ 10 | -ms-text-size-adjust: 100%; /* 2 */ 11 | -webkit-text-size-adjust: 100%; /* 2 */ 12 | } 13 | 14 | /** 15 | * Remove the margin in all browsers (opinionated). 16 | */ 17 | 18 | body { 19 | margin: 0; 20 | } 21 | 22 | /* HTML5 display definitions 23 | ========================================================================== */ 24 | 25 | /** 26 | * Add the correct display in IE 9-. 27 | * 1. Add the correct display in Edge, IE, and Firefox. 28 | * 2. Add the correct display in IE. 29 | */ 30 | 31 | article, 32 | aside, 33 | details, /* 1 */ 34 | figcaption, 35 | figure, 36 | footer, 37 | header, 38 | main, /* 2 */ 39 | menu, 40 | nav, 41 | section, 42 | summary { /* 1 */ 43 | display: block; 44 | } 45 | 46 | /** 47 | * Add the correct display in IE 9-. 48 | */ 49 | 50 | audio, 51 | canvas, 52 | progress, 53 | video { 54 | display: inline-block; 55 | } 56 | 57 | /** 58 | * Add the correct display in iOS 4-7. 59 | */ 60 | 61 | audio:not([controls]) { 62 | display: none; 63 | height: 0; 64 | } 65 | 66 | /** 67 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 68 | */ 69 | 70 | progress { 71 | vertical-align: baseline; 72 | } 73 | 74 | /** 75 | * Add the correct display in IE 10-. 76 | * 1. Add the correct display in IE. 77 | */ 78 | 79 | template, /* 1 */ 80 | [hidden] { 81 | display: none; 82 | } 83 | 84 | /* Links 85 | ========================================================================== */ 86 | 87 | /** 88 | * 1. Remove the gray background on active links in IE 10. 89 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 90 | */ 91 | 92 | a { 93 | background-color: transparent; /* 1 */ 94 | -webkit-text-decoration-skip: objects; /* 2 */ 95 | } 96 | 97 | /** 98 | * Remove the outline on focused links when they are also active or hovered 99 | * in all browsers (opinionated). 100 | */ 101 | 102 | a:active, 103 | a:hover { 104 | outline-width: 0; 105 | } 106 | 107 | /* Text-level semantics 108 | ========================================================================== */ 109 | 110 | /** 111 | * 1. Remove the bottom border in Firefox 39-. 112 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 113 | */ 114 | 115 | abbr[title] { 116 | border-bottom: none; /* 1 */ 117 | text-decoration: underline; /* 2 */ 118 | text-decoration: underline dotted; /* 2 */ 119 | } 120 | 121 | /** 122 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 123 | */ 124 | 125 | b, 126 | strong { 127 | font-weight: inherit; 128 | } 129 | 130 | /** 131 | * Add the correct font weight in Chrome, Edge, and Safari. 132 | */ 133 | 134 | b, 135 | strong { 136 | font-weight: bolder; 137 | } 138 | 139 | /** 140 | * Add the correct font style in Android 4.3-. 141 | */ 142 | 143 | dfn { 144 | font-style: italic; 145 | } 146 | 147 | /** 148 | * Correct the font size and margin on `h1` elements within `section` and 149 | * `article` contexts in Chrome, Firefox, and Safari. 150 | */ 151 | 152 | h1 { 153 | font-size: 2em; 154 | margin: 0.67em 0; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Remove the border on images inside links in IE 10-. 200 | */ 201 | 202 | img { 203 | border-style: none; 204 | } 205 | 206 | /** 207 | * Hide the overflow in IE. 208 | */ 209 | 210 | svg:not(:root) { 211 | overflow: hidden; 212 | } 213 | 214 | /* Grouping content 215 | ========================================================================== */ 216 | 217 | /** 218 | * 1. Correct the inheritance and scaling of font size in all browsers. 219 | * 2. Correct the odd `em` font sizing in all browsers. 220 | */ 221 | 222 | code, 223 | kbd, 224 | pre, 225 | samp { 226 | font-family: monospace, monospace; /* 1 */ 227 | font-size: 1em; /* 2 */ 228 | } 229 | 230 | /** 231 | * Add the correct margin in IE 8. 232 | */ 233 | 234 | figure { 235 | margin: 1em 40px; 236 | } 237 | 238 | /** 239 | * 1. Add the correct box sizing in Firefox. 240 | * 2. Show the overflow in Edge and IE. 241 | */ 242 | 243 | hr { 244 | box-sizing: content-box; /* 1 */ 245 | height: 0; /* 1 */ 246 | overflow: visible; /* 2 */ 247 | } 248 | 249 | /* Forms 250 | ========================================================================== */ 251 | 252 | /** 253 | * 1. Change font properties to `inherit` in all browsers (opinionated). 254 | * 2. Remove the margin in Firefox and Safari. 255 | */ 256 | 257 | button, 258 | input, 259 | select, 260 | textarea { 261 | font: inherit; /* 1 */ 262 | margin: 0; /* 2 */ 263 | } 264 | 265 | /** 266 | * Restore the font weight unset by the previous rule. 267 | */ 268 | 269 | optgroup { 270 | font-weight: bold; 271 | } 272 | 273 | /** 274 | * Show the overflow in IE. 275 | * 1. Show the overflow in Edge. 276 | */ 277 | 278 | button, 279 | input { /* 1 */ 280 | overflow: visible; 281 | } 282 | 283 | /** 284 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 285 | * 1. Remove the inheritance of text transform in Firefox. 286 | */ 287 | 288 | button, 289 | select { /* 1 */ 290 | text-transform: none; 291 | } 292 | 293 | /** 294 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 295 | * controls in Android 4. 296 | * 2. Correct the inability to style clickable types in iOS and Safari. 297 | */ 298 | 299 | button, 300 | html [type="button"], /* 1 */ 301 | [type="reset"], 302 | [type="submit"] { 303 | -webkit-appearance: button; /* 2 */ 304 | } 305 | 306 | /** 307 | * Remove the inner border and padding in Firefox. 308 | */ 309 | 310 | button::-moz-focus-inner, 311 | [type="button"]::-moz-focus-inner, 312 | [type="reset"]::-moz-focus-inner, 313 | [type="submit"]::-moz-focus-inner { 314 | border-style: none; 315 | padding: 0; 316 | } 317 | 318 | /** 319 | * Restore the focus styles unset by the previous rule. 320 | */ 321 | 322 | button:-moz-focusring, 323 | [type="button"]:-moz-focusring, 324 | [type="reset"]:-moz-focusring, 325 | [type="submit"]:-moz-focusring { 326 | outline: 1px dotted ButtonText; 327 | } 328 | 329 | /** 330 | * Change the border, margin, and padding in all browsers (opinionated). 331 | */ 332 | 333 | fieldset { 334 | border: 1px solid #c0c0c0; 335 | margin: 0 2px; 336 | padding: 0.35em 0.625em 0.75em; 337 | } 338 | 339 | /** 340 | * 1. Correct the text wrapping in Edge and IE. 341 | * 2. Correct the color inheritance from `fieldset` elements in IE. 342 | * 3. Remove the padding so developers are not caught out when they zero out 343 | * `fieldset` elements in all browsers. 344 | */ 345 | 346 | legend { 347 | box-sizing: border-box; /* 1 */ 348 | color: inherit; /* 2 */ 349 | display: table; /* 1 */ 350 | max-width: 100%; /* 1 */ 351 | padding: 0; /* 3 */ 352 | white-space: normal; /* 1 */ 353 | } 354 | 355 | /** 356 | * Remove the default vertical scrollbar in IE. 357 | */ 358 | 359 | textarea { 360 | overflow: auto; 361 | } 362 | 363 | /** 364 | * 1. Add the correct box sizing in IE 10-. 365 | * 2. Remove the padding in IE 10-. 366 | */ 367 | 368 | [type="checkbox"], 369 | [type="radio"] { 370 | box-sizing: border-box; /* 1 */ 371 | padding: 0; /* 2 */ 372 | } 373 | 374 | /** 375 | * Correct the cursor style of increment and decrement buttons in Chrome. 376 | */ 377 | 378 | [type="number"]::-webkit-inner-spin-button, 379 | [type="number"]::-webkit-outer-spin-button { 380 | height: auto; 381 | } 382 | 383 | /** 384 | * 1. Correct the odd appearance in Chrome and Safari. 385 | * 2. Correct the outline style in Safari. 386 | */ 387 | 388 | [type="search"] { 389 | -webkit-appearance: textfield; /* 1 */ 390 | outline-offset: -2px; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X. 395 | */ 396 | 397 | [type="search"]::-webkit-search-cancel-button, 398 | [type="search"]::-webkit-search-decoration { 399 | -webkit-appearance: none; 400 | } 401 | 402 | /** 403 | * Correct the text style of placeholders in Chrome, Edge, and Safari. 404 | */ 405 | 406 | ::-webkit-input-placeholder { 407 | color: inherit; 408 | opacity: 0.54; 409 | } 410 | 411 | /** 412 | * 1. Correct the inability to style clickable types in iOS and Safari. 413 | * 2. Change font properties to `inherit` in Safari. 414 | */ 415 | 416 | ::-webkit-file-upload-button { 417 | -webkit-appearance: button; /* 1 */ 418 | font: inherit; /* 2 */ 419 | } 420 | -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minigrid-site", 3 | "version": "0.0.0", 4 | "description": "Minigrid site", 5 | "scripts": { 6 | "build": "node build.js", 7 | "gh-pages": "git-directory-deploy --directory . --branch gh-pages", 8 | "deploy": "npm run build && npm run gh-pages" 9 | }, 10 | "keywords": [], 11 | "author": { 12 | "name": "Henrique Alves", 13 | "email": "henriquea@gmail.com", 14 | "twitter": "@healves82" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/henriquea/minigrid.git" 19 | }, 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/henriquea/minigrid/issues" 23 | }, 24 | "homepage": "http://alves.im/minigrid", 25 | "devDependencies": { 26 | "git-directory-deploy": "^1.5.0", 27 | "handlebars": "^4.0.5", 28 | "html-minifier": "^2.0.0", 29 | "remark": "^4.2.1", 30 | "remark-html": "^3.0.0", 31 | "remark-yaml-config": "^3.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /site/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html { 6 | font-size: 16px; 7 | } 8 | 9 | body { 10 | padding: 0; 11 | margin: 0; 12 | color: #212121; 13 | background: #fff; 14 | text-rendering: geometricPrecision; 15 | line-height: 24px; 16 | font-family: -apple-system, 'Segoe UI', 'Roboto', 'Helvetica Neue', Helvetica, sans-serif; 17 | } 18 | 19 | body.debug { 20 | background-image: repeating-linear-gradient(to bottom, transparent 0px, transparent 23px, #DBE2EF 23px, #DBE2EF 24px); 21 | } 22 | 23 | h1 { 24 | line-height: 24px; 25 | margin: 24px 0; 26 | margin-top: 48px; 27 | } 28 | 29 | h1:first-of-type { 30 | margin-top: 24px; 31 | } 32 | 33 | h2 { 34 | line-height: 24px; 35 | margin: 24px 0; 36 | position: relative; 37 | top: 4px; 38 | } 39 | 40 | p { 41 | line-height: 24px; 42 | margin: 24px 0; 43 | position: relative; 44 | top: 6px; 45 | } 46 | 47 | /* logo */ 48 | p:first-of-type { 49 | margin: 0; 50 | line-height: 0; 51 | } 52 | 53 | ul > li { 54 | line-height: 24px; 55 | margin: 24px 0; 56 | } 57 | 58 | a { 59 | color: #212121; 60 | text-decoration: none; 61 | font-weight: bold; 62 | } 63 | 64 | a:hover { 65 | color: #6078EA; 66 | } 67 | 68 | pre, code { 69 | font-size: 14px; 70 | font-family: Menlo, Monaco, 'Lucida Console', monospace, serif; 71 | } 72 | 73 | pre > code { 74 | padding: 12px; 75 | background: #f4f6f8; 76 | display: block; 77 | overflow-y: hidden; 78 | overflow-x: auto; 79 | } 80 | 81 | .container { 82 | width: 100%; 83 | max-width: 864px; 84 | padding: 0 24px; 85 | margin: 96px auto; 86 | } 87 | 88 | ul:first-child { 89 | position: absolute; 90 | top: 0; 91 | left: 0; 92 | margin: 0; 93 | padding: 24px; 94 | list-style: none; 95 | width: 100%; 96 | text-align: right; 97 | } 98 | 99 | ul > li { 100 | display: inline-block; 101 | margin: 0; 102 | margin-right: 24px; 103 | position: relative; 104 | top: 6px; 105 | } 106 | 107 | ul:last-child { 108 | margin: 0; 109 | padding: 48px 0 0 0; 110 | text-align: left; 111 | display: flex; 112 | } 113 | 114 | ul:last-child > li:last-child { 115 | margin-left: auto; 116 | margin-right: 0; 117 | top: 0; 118 | } 119 | 120 | @media (max-width: 600px) { 121 | .container { 122 | max-width: inherit; 123 | } 124 | ul:first-child { 125 | width: auto; 126 | text-align: left; 127 | } 128 | ul:last-child { 129 | display: block; 130 | } 131 | ul:last-child > li:last-child { 132 | margin: 24px 0 0 0; 133 | display: block; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /site/template.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{title}} 9 | 10 | 11 | 12 | 13 |
{{{content}}}
14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* @license Minigrid v3.1.1 – minimal cascading grid layout http://alves.im/minigrid */ 2 | (function (root, factory) { 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof exports === 'object') { 6 | module.exports = factory(); 7 | } else { 8 | root.Minigrid = factory(); 9 | } 10 | 11 | }(this, function(exports){ 12 | 'use strict'; 13 | 14 | function extend(a, b) { 15 | for (var key in b) { 16 | if (b.hasOwnProperty(key)) { 17 | a[key] = b[key]; 18 | } 19 | } 20 | return a; 21 | } 22 | 23 | var Minigrid = function(props) { 24 | var containerEle = props.container instanceof Node ? ( 25 | props.container 26 | ) : ( 27 | document.querySelector(props.container) 28 | ); 29 | 30 | var itemsNodeList = props.item instanceof NodeList ? 31 | props.item : containerEle.querySelectorAll(props.item); 32 | 33 | this.props = extend(props, { 34 | container: containerEle, 35 | nodeList: itemsNodeList 36 | }); 37 | 38 | } 39 | 40 | Minigrid.prototype.mount = function() { 41 | if (!this.props.container) { 42 | return false; 43 | } 44 | if (!this.props.nodeList || this.props.nodeList.length === 0) { 45 | return false; 46 | } 47 | var gutter = ( 48 | typeof this.props.gutter === 'number' && 49 | isFinite(this.props.gutter) && 50 | Math.floor(this.props.gutter) === this.props.gutter 51 | ) ? this.props.gutter : 0; 52 | 53 | var done = this.props.done; 54 | var containerEle = this.props.container; 55 | var itemsNodeList = this.props.nodeList; 56 | 57 | containerEle.style.width = ''; 58 | 59 | var forEach = Array.prototype.forEach; 60 | var containerWidth = containerEle.getBoundingClientRect().width; 61 | var firstChildWidth = itemsNodeList[0].getBoundingClientRect().width + gutter; 62 | var cols = Math.max(Math.floor((containerWidth - gutter) / firstChildWidth), 1); 63 | var count = 0; 64 | 65 | containerWidth = (firstChildWidth * cols + gutter) + 'px'; 66 | containerEle.style.width = containerWidth; 67 | containerEle.style.position = 'relative'; 68 | 69 | var itemsGutter = []; 70 | var itemsPosX = []; 71 | 72 | for ( var g = 0 ; g < cols ; ++g ) { 73 | itemsPosX.push(g * firstChildWidth + gutter); 74 | itemsGutter.push(gutter); 75 | } 76 | 77 | // RTL support 78 | if (this.props.rtl) { 79 | itemsPosX.reverse(); 80 | } 81 | 82 | forEach.call(itemsNodeList, function (item) { 83 | var itemIndex = itemsGutter 84 | .slice(0) 85 | .sort(function (a, b) { 86 | return a - b; 87 | }) 88 | .shift(); 89 | itemIndex = itemsGutter.indexOf(itemIndex); 90 | 91 | var posX = parseInt(itemsPosX[itemIndex]); 92 | var posY = parseInt(itemsGutter[itemIndex]); 93 | 94 | item.style.position = 'absolute'; 95 | item.style.webkitBackfaceVisibility = item.style.backfaceVisibility = 'hidden'; 96 | item.style.transformStyle = 'preserve-3d'; 97 | item.style.transform = 'translate3D(' + posX + 'px,' + posY + 'px, 0)'; 98 | 99 | itemsGutter[itemIndex] += item.getBoundingClientRect().height + gutter; 100 | count = count + 1; 101 | 102 | }); 103 | 104 | containerEle.style.display = ''; 105 | 106 | var containerHeight = itemsGutter 107 | .slice(0) 108 | .sort(function (a, b) { 109 | return a - b; 110 | }) 111 | .pop(); 112 | 113 | containerEle.style.height = containerHeight + 'px'; 114 | 115 | if (typeof done === 'function') { 116 | done(itemsNodeList); 117 | } 118 | } 119 | 120 | return Minigrid; 121 | 122 | })); 123 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | 'use restrict'; 2 | 3 | /* 4 | var grid = new minigrid({ 5 | container: '.cards', 6 | item: '.card', 7 | gutter: 6 8 | }); 9 | grid.mount(); 10 | **/ 11 | 12 | var minigrid = require('../src/index'); 13 | var test = require('tape'); 14 | 15 | test('minigrid init with empty node list', function(t){ 16 | var grid = new minigrid({ 17 | container: document.createElement('div') 18 | }); 19 | t.equal(grid.mount(), false, 'return false'); 20 | t.end(); 21 | }); 22 | 23 | test('minigrid init and get nodeList', function(t){ 24 | var container = document.createElement('div'); 25 | container.classList.add('cards'); 26 | document.body.appendChild(container); 27 | var gridItem = document.createElement('div'); 28 | gridItem.classList.add('card'); 29 | container.appendChild(gridItem); 30 | var grid = new minigrid({ 31 | container: '.cards', 32 | item: '.card', 33 | done: function(nodeList) { 34 | t.equal(typeof nodeList.length, 'number', 'nodeList.lenght is number'); 35 | t.equal(nodeList.length > 0, true, nodeList.length + ' grid items'); 36 | t.end(); 37 | } 38 | }); 39 | grid.mount(); 40 | }); 41 | 42 | test('minigrid init with existing nodeList', function(t){ 43 | 44 | var container = document.createElement('div'); 45 | document.body.appendChild(container); 46 | 47 | var numGridItems = 5; 48 | 49 | for(var i = 0; i< numGridItems; i++){ 50 | var item = document.createElement('div'); 51 | container.appendChild(item); 52 | } 53 | 54 | var items = container.querySelectorAll('div'); 55 | 56 | var grid = new minigrid({ 57 | container: container, 58 | item: items, 59 | done: function(nodeList){ 60 | t.equal(typeof nodeList.length, 'number', 'nodeList.lenght is number'); 61 | t.equal(nodeList.length > 0, true, nodeList.length + ' grid items'); 62 | t.end(); 63 | } 64 | }); 65 | grid.mount(); 66 | }); 67 | --------------------------------------------------------------------------------