<div class="grid">
  <div class="item" data-id="1">
    <div class="item-content">1</div>
  </div>
  <div class="item" data-id="2">
    <div class="item-content">2</div>
  </div>
  <div class="item" data-id="3">
    <div class="item-content">3</div>
  </div>
  <div class="item" data-id="4">
    <div class="item-content">4</div>
  </div>
  <div class="item" data-id="5">
    <div class="item-content">5</div>
  </div>
  <div class="item" data-id="6">
    <div class="item-content">6</div>
  </div>
  <div class="item" data-id="7">
    <div class="item-content">7</div>
  </div>
  <div class="item" data-id="8">
    <div class="item-content">8</div>
  </div>
  <div class="item" data-id="9">
    <div class="item-content">9</div>
  </div>
  <div class="item" data-id="10">
    <div class="item-content">10</div>
  </div>
  <div class="item" data-id="11">
    <div class="item-content">11</div>
  </div>
  <div class="item" data-id="12">
    <div class="item-content">12</div>
  </div>
  <div class="item" data-id="13">
    <div class="item-content">13</div>
  </div>
  <div class="item" data-id="14">
    <div class="item-content">14</div>
  </div>
  <div class="item" data-id="15">
    <div class="item-content">15</div>
  </div>
  <div class="item" data-id="16">
    <div class="item-content">16</div>
  </div>
  <div class="item" data-id="17">
    <div class="item-content">17</div>
  </div>
  <div class="item" data-id="18">
    <div class="item-content">18</div>
  </div>
  <div class="item" data-id="19">
    <div class="item-content">19</div>
  </div>
  <div class="item" data-id="20">
    <div class="item-content">20</div>
  </div>
</div>
.grid {
  position: relative;
}
.item {
  position: absolute;
  width: 200px;
  height: 200px;
  line-height: 200px;
  margin: 5px;
  z-index: 1;
}
.item.muuri-item-hidden {
  z-index: 0;
}
.item.muuri-item-releasing {
  z-index: 2;
}
.item.muuri-item-dragging {
  z-index: 3;
}
.item-content {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  background: red;
  font-size: 50px;
  color: white;
  cursor: pointer;
}
.item.muuri-item-dragging .item-content {
  background: blue;
}
.item.muuri-item-releasing .item-content {
  background: blueViolet;
}
initGrid();

function initGrid() {
  var grid = new Muuri('.grid', {
    dragEnabled: true,
    layoutOnInit: false
  }).on('move', function () {
    saveLayout(grid);
  });

  var layout = window.localStorage.getItem('layout');
  if (layout) {
    loadLayout(grid, layout);
  } else {
    grid.layout(true);
  }
}

function serializeLayout(grid) {
  var itemIds = grid.getItems().map(function (item) {
    return item.getElement().getAttribute('data-id');
  });
  return JSON.stringify(itemIds);
}

function saveLayout(grid) {
  var layout = serializeLayout(grid);
  window.localStorage.setItem('layout', layout);
}

function loadLayout(grid, serializedLayout) {
  var layout = JSON.parse(serializedLayout);
  var currentItems = grid.getItems();
  var currentItemIds = currentItems.map(function (item) {
    return item.getElement().getAttribute('data-id')
  });
  var newItems = [];
  var itemId;
  var itemIndex;

  for (var i = 0; i < layout.length; i++) {
    itemId = layout[i];
    itemIndex = currentItemIds.indexOf(itemId);
    if (itemIndex > -1) {
      newItems.push(currentItems[itemIndex])
    }
  }

  grid.sort(newItems, {layout: 'instant'});
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.3.2/web-animations.min.js
  2. https://cdn.jsdelivr.net/gh/haltu/muuri@0.9.5/dist/muuri.min.js