This is a custom element that fit elements into a grid using a bin-packing algorithm. The result is similar to the grid used on pinterest and other sites.
It will try to fit everything and leave no spaces, but in case there are gaps left, it will create div elements to fill them.
And just for the record, the size of the elements are never changed at all; the elements are only reordered.
Also, this element is responsive.
It is created using only vanilla js and it has no dependencies! (except, of course, the webcomponents.js polyfill)
hidden
attribute to make an bin-packing-item
element to not use space on the grid.detect-size
attribute. Using it, is not necessary to manually set the rows
and cols
and instead, it tries to automatically detect how many are necessary.<bin-packing-item>
elements and call the reflow
method on the grid element to repackage and reorder the grid.This uses a variation of the best-fit algorithm; it tries to fit each element and check the possible positions but it first gives priority to the one that keeps the height of the grid smaller.
Install the component using Bower:
$ bower install bin-packing-grid --save
Or download as ZIP.
Import Web Components' polyfill:
<script src="https://github.com/chris-l/bin-packing-grid/raw/master/bower_components/webcomponentsjs/webcomponents.min.js"></script>
Import the bin-packing-grid element:
<link rel="import" href="https://github.com/chris-l/bin-packing-grid/blob/master/bower_components/bin-packing-grid/dist/bin-packing-grid.html">
Start using it!
<bin-packing-grid cell-size="150">
<bin-packing-item rows="1" cols="2">2x1</bin-packing-item>
<bin-packing-item rows="2" cols="1">1x2</bin-packing-item>
<bin-packing-item detect-size><img src="https://github.com/chris-l/bin-packing-grid/raw/master/someimage.jpg"></bin-packing-item>
<bin-packing-item rows="2" cols="3">3x2</bin-packing-item>
</bin-packing-grid>
The <bin-packing-grid>
creates a grid formed by squares, which each side has the measure of cell-size
in pixels (default 100). Each one of those squares is separated by a gutter determined by gutter-size
also in pixels (default 5).
The size of each <bin-packing-item>
element is determined by the amount of rows
(number of squares, plus gutter space, vertically) and cols
(number of squares, plus gutter space, horizontally).
Instead of manually specifying rows
and cols
, is possible to add the detect-size
attribute (with any or no value) to try to detect the required number of rows
and cols
.
The <bin-packing-item>
elements don't have colours, backgrounds or any visual style by default (except a border to make it visible). The only style properties added are the ones required to set the size and positionate the element into the grid.
Is up to the developer to add any other desired style. By using the transition css property, is possible to animate the movement of elements.
To fill the gaps, <div>
elements with the bin-packing-filler class will be created. Those elements are created into the shadow dom. You can target that element for styling with a rule like this:
bin-packing-grid::shadow .bin-packing-filler {
background-color: blue;
}
Just create a <bin-packing-item>
element, attach it to the grid, and call reflow
.
var item, grid;
grid = document.getElementsByTagName('bin-packing-grid')[0];
item = document.createElement('bin-packing-item');
item.rows = 3;
item.cols = 3;
grid.appendChild(item);
grid.reflow();
Property | Attribute | Type | Default | Description |
---|---|---|---|---|
cellSize |
cell-size |
number | 100 |
Size in pixels for each cell |
gutterSize |
gutter-size |
number | 5 |
Size in pixels for the space used to separate elements |
Property | Attribute | Type | Default | Description |
---|---|---|---|---|
rows |
rows |
number | 1 |
Height of the item, using the cellSize of the <bin-packing-grid> parent as unit. |
cols |
cols |
number | 1 |
Width of the item, using the cellSize of the <bin-packing-grid> parent as unit. |
detectSize |
detect-size |
boolean | false |
Automatically set the rows and cols required for the content inside of the <bin-packing-item> element. |
hidden |
hidden |
boolean | false |
Using the attribute hidden will cause the element not only to be not displayed, but also it will not use space on the grid. |
git checkout -b my-new-feature
git commit -m 'Add some feature'
git push origin my-new-feature