Install Muuri
masterYou can install Muuri via npm or by linking directly to a CDN.
npm:
npm install muuriCDN (Production):
<script src="https://cdn.jsdelivr.net/npm/muuri@0.9.5/dist/muuri.min.js"></script>repository·master·Indexed 27 days ago
https://github.com/haltu/muuriA high-performance JavaScript layout engine for building responsive, sortable, filterable, and draggable layouts. Version 0.9.5 abstracts the complexity of item positioning, animations, and drag-and-drop interactions.
You can install Muuri via npm or by linking directly to a CDN.
npm:
npm install muuriCDN (Production):
<script src="https://cdn.jsdelivr.net/npm/muuri@0.9.5/dist/muuri.min.js"></script>To use Muuri, your HTML must follow these rules:
Example structure:
<div class="grid">
<div class="item">
<div class="item-content">
<!-- Your custom content goes here -->
</div>
</div>
</div><div class="grid">
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
This can be anything.
<!-- Safe zone ends -->
</div>
</div>
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="my-custom-content">
Yippee!
</div>
<!-- Safe zone ends -->
</div>
</div>
</div>Muuri requires specific CSS properties to function correctly:
position of relative, absolute, or fixed.overflow: auto; or overflow: scroll; directly on the grid element. This causes item jumping during drags. Instead, wrap the grid in a container and set the overflow on that wrapper.position: absolute;.margin on the item elements to control spacing between items.Example CSS:
.grid {
position: relative;
}
.item {
display: block;
position: absolute;
width: 100px;
height: 100px;
margin: 5px;
z-index: 1;
background: #000;
color: #fff;
}
.item.muuri-item-dragging {
z-index: 3;
}
.item.muuri-item-releasing {
z-index: 2;
}
.item.muuri-item-hidden {
z-index: 0;
}
.item-content {
position: relative;
width: 100%;
height: 100%;
}Muuri uses the Web Animations API by default. If you need to support browsers that do not have native Web Animations support, you must install the web-animations-js polyfill.
npm:
npm install web-animations-jsCDN:
<script src="https://cdn.jsdelivr.net/npm/web-animations-js@2.3.2/web-animations.min.js"></script>Proper CSS positioning is required for Muuri to function correctly:
position set to relative, absolute, or fixed. Never set overflow: auto; or overflow: scroll; directly on the grid element; use a wrapper element instead to avoid layout jumps during dragging.position: absolute; and display: block;.margin on the item elements to control spacing between items.Example CSS:
.grid {
position: relative;
}
.item {
display: block;
position: absolute;
width: 100px;
height: 100px;
margin: 5px;
z-index: 1;
background: #000;
color: #fff;
}
.item.muuri-item-dragging {
z-index: 3;
}
.item.muuri-item-releasing {
z-index: 2;
}
.item.muuri-item-hidden {
z-index: 0;
}
.item-content {
position: relative;
width: 100%;
height: 100%;
}Muuri uses the Web Animations API by default. If you need to support browsers that do not have this API, you must install and include the web-animations-js polyfill.
npm install web-animations-jsTo use Muuri, your HTML must follow a specific structure:
Example markup:
<div class="grid">
<div class="item">
<div class="item-content">
<!-- Your custom content goes here -->
This is the safe zone.
</div>
</div>
<div class="item">
<div class="item-content">
<div class="my-custom-content">Yippee!</div>
</div>
</div>
</div><div class="grid">
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
This can be anything.
<!-- Safe zone ends -->
</div>
</div>
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="my-custom-content">Yippee!</div>
<!-- Safe zone ends -->
</div>
</div>
</div>You can specify custom class names that Muuri applies to items during specific interaction states (positioning, dragging, releasing) or for the drag placeholder. This is useful for applying specific styles or animations during these transitions.
var grid = new Muuri(elem, {
itemPositioningClass: 'foo-item-positioning',
itemDraggingClass: 'foo-item-dragging',
itemReleasingClass: 'foo-item-releasing',
itemPlaceholderClass: 'foo-item-placeholder'
});Control when Muuri triggers the layout method automatically.
layoutOnResize: Determines if the grid should re-layout when the window is resized.false: Disable automatic layout.true: Layout instantly on resize.number: Wait for the specified number of milliseconds (debounce) before positioning items after a resize event.150.layoutOnInit: Determines if Muuri should trigger layout automatically when the grid is initialized.true.// No layout on resize.
var grid = new Muuri(elem, {
layoutOnResize: false,
});
// Layout on resize (instantly).
var grid = new Muuri(elem, {
layoutOnResize: true,
});
// Layout on resize (with 200ms debounce).
var grid = new Muuri(elem, {
layoutOnResize: 200,
});
// Disable layout on init.
var grid = new Muuri(elem, {
layoutOnInit: false,
});The items option defines the initial elements to be used in the grid. These elements should be children of the grid element. If provided elements are not currently in the DOM, Muuri will append them to the grid.
You can provide:
NodeList or HTMLCollectionnullBy default, all current child elements of the grid element are used ('*').
// Use specific items.
var grid = new Muuri(elem, {
items: [elemA, elemB, elemC],
});
// Use node list.
var grid = new Muuri(elem, {
items: elem.querySelectorAll('.item'),
});
// Use selector.
var grid = new Muuri(elem, {
items: '.item',
});Set the easing function for show and hide animations. Accepts any valid Animation easing value.
'ease'.'ease'.string.var grid = new Muuri(elem, {
showEasing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
hideEasing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
});Customize the logic that determines when an item starts moving during a drag.
Option 1: Object configuration Provide an object to configure the default predicate:
distance: Number. Pixels to drag before movement starts. Default 0.delay: Number. Milliseconds to wait before movement starts. Default 0.Option 2: Custom function
Provide a function function(item, event) that returns true to start moving or false to prevent movement.
Note: If providing a custom function, you should call Muuri.ItemDrag.defaultStartPredicate(item, e) for the final event (e.isFinal) and for standard behavior to ensure internal state is reset correctly.
// Configure the default predicate
var grid = new Muuri(elem, {
dragStartPredicate: {
distance: 10,
delay: 100,
},
});
// Provide your own predicate with fallback
var grid = new Muuri(elem, {
dragStartPredicate: function (item, e) {
if (e.isFinal) {
Muuri.ItemDrag.defaultStartPredicate(item, e);
return;
}
// Prevent first item from being dragged.
if (grid.getItems()[0] === item) {
return false;
}
return Muuri.ItemDrag.defaultStartPredicate(item, e);
},
});