A minimalist masonry layout is written in vanilla JS, with no dependencies.
columns.js creates a masonry grid by wrapping each column of items in an element. Masonry grid is then created without the need for absolute positioning nor css transforms.
- Blazing fast, vanilla js
- Written as ES6 module, no dependencies
- No inline styles, no absolute positioning, no transforms
- Responsive support, minimal configuration
- Multiple partitioning algorithms
No dependencies! Written in plain javascript.
$ npm install columns.js
or
yarn add columns.js
Following example demonstrates creating a masonry grid with 3 columns:
import Columns from 'columns.js';
let grid = new Columns(document.getElementById('columns'), {
columns: 3
});
<div id="columns">
<img src="https://picsum.photos/400/200/?random">
<img src="https://picsum.photos/300/500/?random">
...
</div>
Dynamically append elements to the grid:
let item = new Image();
item.src = 'https://picsum.photos/400/200/?random';
grid.append(item);
new Columns(document.getElementById('columns'), {
/**
* Number of columns (Mandatory)
*/
columns: 1,
/**
* Responsive settings (Optional)
*
* Each key represents a screen size and each value
* is corresponding number of columns
*
* Example:
* < 480px -> 1 column
* > 480px and < 839px -> 3 columns
* > 840px -> 4 columns
*/
breakpoints: {
480: 3,
840: 4
},
/**
* Html class added to grid column elements (Optional)
*/
column_class: 'column-js',
/**
* Choose algorithm used for partitioning elements into columns (Optional)
*
* 'greedy' (default) or 'chronological'
*/
algorithm: 'greedy'
});
This section provides information on algorithms implemented by columns.js for partitioning elements into columns.
It currently supports two algorithms – greedy
and chronological
Greedy algorithm - greedy
(default)
The algorithm iterates through the elements in descending order, assigning each of them to whichever column has the smaller total height.
This approach reduces the difference between column heights while sacrificing the chronological order of items.
As an improvement, column.js implementation preserves chronological order of items within one column.
The algorithm iterates through the elements, assigning them to columns in chronological order.
There is no optimization of column heights.
grid.count(); // Get current number of columns
grid.append(element); // Append new html element
grid.render(); // Re-flow the grid
grid.setOptions(options)
columns.js does not apply any inline styles. No absolute positioning. No transformations.
Instead, columns.js maintains columns
data attribute on the wrapper element with a current column count value, which can be used for styling:
[data-columns] {
display: flex;
flex-wrap: wrap;
}
[data-columns="3"] > * {
flex-basis: calc(100% / 3);
}
[data-columns="4"] > * {
flex-basis: calc(100% / 4);
}
Here's a handy mixin:
@mixin columnsjs {
display: flex;
flex-wrap: wrap;
@for $i from 1 through 9 {
&[data-columns="#{$i}"] {
& > * {
flex-basis: calc(100% / #{$i});
}
}
}
}
#columns {
@include columnsjs;
}
columns.js relies on modern ES6 features, some of which are not supported by IE. Polyfills for following methods are needed:
- NodeList.prototype.forEach
- Array.from
- Object.entries
- Element.prototype.append
Thanks @hybridvision for composing the list. :)
- Removing an element from the grid
- Event system