Home

Awesome

Slip

A tiny library for interactive swiping and reordering of elements in lists on touch screens. No dependencies. BSD Licensed.

Try live demo (best on a touchscreen device)

Supports iOS Safari, Firefox Mobile, Chrome Mobile, Opera Mobile (Presto and Blink).

Demo

Usage

You interact with the library via custom DOM events for swipes/reordering. Call new Slip(<element>) to make element's children swipeable and add event listeners for any of the following events:

Example

var list = document.querySelector('ul#slippylist');
new Slip(list);

list.addEventListener('slip:beforeswipe', function(e) {
    if (shouldNotSwipe(e.target)) {
        e.preventDefault(); // won't move sideways if prevented
    }
});

list.addEventListener('slip:swipe', function(e) {
    // e.target list item swiped
    if (thatWasSwipeToRemove) {
        // list will collapse over that element
        e.target.parentNode.removeChild(e.target);
    } else {
        e.preventDefault(); // will animate back to original position
    }
});

list.addEventListener('slip:beforereorder', function(e) {
    if (shouldNotReorder(e.target)) {
        // if prevented element won't move vertically
        e.preventDefault();
    }
});

list.addEventListener('slip:beforewait', function(e) {
    if (isScrollingKnob(e.target)) {
        // if prevented element will be dragged (instead of page scrolling)
        e.preventDefault();
    }
});

list.addEventListener('slip:reorder', function(e) {
    // e.target list item reordered.
    if (reorderedOK) {
        e.target.parentNode.insertBefore(e.target, e.detail.insertBefore);
    } else {
        // element will fly back to original position
        e.preventDefault();
    }
});

See live example.

CSS

The library doesn't need any special CSS, but there are some tweaks that can make it nicer.

If you don't need text selection you can disable it to make dragging easier:

li {
    user-select: none;
}

You probably don't want horizontal scrollbar when elements are swiped off the list (slip-swiping-container class is set on container element only when necessary):

.slip-swiping-container {
    overflow-x: hidden;
}

Class slip-reordering is set on list element that is being dragged:

.slip-reordering {
    box-shadow: 0 2px 10px rgba(0,0,0,0.45);
}

When an item is dragged, z-index is set to 99999 on the element, so that it floats above the other elements in the list. In order to make this effective in some browsers, you'll need to set position: relative on the list items.

li {
    position: relative;
}

iOS also tends to add highlight color to tapped areas. If that bothers you, apply -webkit-tap-highlight-color: rgba(0,0,0,0); to tappable elements.

Configuration

You can also provide an options object when initialising Slip:

new Slip(element, {
    ignoredElements: '#imnothere' // Allows you to provide any valid CSS selector, elements matching it will be ignored by Slip.
        // Useful when you have invisible elements in your container but will cause bugs when used on visible items.
})

Accessibility and focus management

In the source code there's an accessibility object with settings for enabling ARIA roles on elements and focus when elements are used. Set focus: true in that array for potentially improved screen reader use.

Please note that Slip does not support keyboard interaction (pull requests are welcome), so you need to provide your own keyboard-accessible alternative.

TODO

Old browsers

Moving between two lists

For sake of simplicity of implementation and interaction dragging works only within a single list. If you need complex drag'n'drop, consider another, more generic library.

If you only need sorting between two lists (positioned one under another), then you can cheat a little by adding a non-draggable item to the list and styling it to look like a gap between the two lists.