Muuri

repository·master·Indexed 27 days ago

https://github.com/haltu/muuri

A 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.

Tokens
31K
Snippets
99
Records
132
Agent score
92%

What's inside Muuri

  1. Configure Muuri HTML markup

    master

    To use Muuri, your HTML must follow these rules:

    1. Grid Container: Every grid needs a container element.
    2. Grid Items: Each item must consist of at least two elements:
      • An outer element used for positioning.
      • An inner element (the first direct child of the outer element) used for animating visibility (show/hide). This is your 'safe zone' for custom markup.

    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>
  2. Configure Muuri Styles and CSS Requirements

    master

    Muuri requires specific CSS properties to function correctly:

    • Grid Element: Must have a CSS position of relative, absolute, or fixed.
    • Grid Element Overflow: Never set 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.
    • Item Elements: Must have position: absolute;.
    • Item Animations: Do not apply CSS transitions or animations to the item elements themselves, as they will conflict with Muuri's internal engine.
    • Gaps: Use 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%;
    }
  3. Install Web Animations Polyfill

    master

    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-js

    CDN:

    <script src="https://cdn.jsdelivr.net/npm/web-animations-js@2.3.2/web-animations.min.js"></script>
  4. Configure Muuri CSS styles

    master

    Proper CSS positioning is required for Muuri to function correctly:

    1. Grid Element: Must have 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.
    2. Item Elements: Must have position: absolute; and display: block;.
    3. Animations: Do not apply CSS transitions or animations to the item elements themselves, as they will conflict with Muuri's internal engine.
    4. Gaps: Use 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%;
    }
  5. Install Web Animations Polyfill for Muuri

    master

    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-js
  6. Configure Muuri Markup Structure

    master

    To use Muuri, your HTML must follow a specific structure:

    1. Grid Container: A single container element (the grid element).
    2. Grid Items: Each item must consist of at least two elements:
      • Outer Element: Used by Muuri for positioning.
      • Inner Element (the first direct child of the outer element): Used by Muuri to animate visibility (show/hide methods). You can place your custom content inside this inner element.

    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>
  7. Configure Muuri item state CSS classes

    master

    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'
    });
  8. Configure layout behavior on resize and init

    master

    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.
      • Default: 150.
    • layoutOnInit: Determines if Muuri should trigger layout automatically when the grid is initialized.
      • Default: 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,
    });
  9. Configure initial items in Muuri

    master

    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:

    • An array of elements
    • A NodeList or HTMLCollection
    • A CSS selector string (Muuri will use this to filter current child elements of the container)
    • null

    By 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',
    });
  10. Configure show and hide animation easing

    master

    Set the easing function for show and hide animations. Accepts any valid Animation easing value.

    • showEasing: Default is 'ease'.
    • hideEasing: Default is 'ease'.
    • Accepted types: 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)',
    });
  11. Configure dragStartPredicate

    master

    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);
      },
    });