Lightweight vanillajs micro-library for creating sortable lists and grids using native HTML5 drag and drop API.
A fair warning: this repository is currently not being actively developed. It works pretty fine, but if you find any issues you will need to fix them yourself. I try to keep the dependencies up to date and will happily help you fix issues and merge PRs for bugfixes or new features.
Looking for Co-Maintainer
If you are interested in actively helping with maintaining & improving this project please send me a message via twitter @lukasoppermann or email email@example.com with a short text of what you would like to do on the project. This may be something small like sorting issues and helping with questions and small bugs (if you have little time or are not that experienced) or something big like tackling big features.
- Only 2KB (minified and gzipped).
- Built using native HTML5 drag and drop API. No dependencies.
- Supports both list and grid style layouts.
- Supported Browsers: Current versions of all major browsers (Chrome, Firefox, Safari, Opera, Edge), IE11+ (Polyfill required)
- Available as ES6 Module, AMD, CommonJS and iffe with
Demo: Check out the examples
If you would like to add an adapter to the list, please create an issue with the link to your adapter.
We recommend installing the package via npm.
npm install html5sortable --save
Once you install the package using
npm or downloading the latest release (don't use the master branch), load file you need from the
dist/ directory, e.g.
dist/html.sortable.min.js for the minified iife version.
- iffe (loading file via script tag):
- ES6 Module:
- CommonJS Module:
- AMD Module:
Still using bower?
bower install https://github.com/lukasoppermann/html5sortable.git
You can find the examples online or test locally. Warning: the online demo is just to show off the features and is most likely not up to date. Please study this readme file for the current way of implementing and using
sortable method to create a sortable list:
.sortable-placeholder CSS selectors to change the styles of the placeholder. You may change the class by setting the
placeholderClass option in the config object.
You can nest sortables inside each other. However, take care to add a wrapper around the items, a sortable-item can not at the same time be a
<!-- Sortable -->Item 1<!-- Nested Sortable; Wrapping container needed -->Subitem 1Subitem 2Item 2
NOTE: Events can be listened on any element from the group (when using
connectWith), since the same event will be dispatched on all of them.
sortstart event if you want to do something when sorting starts:
sortstop event if you want to do something when sorting stops:
sortupdate event if you want to do something when the order changes (e.g. storing the new order):
items option to specify which items inside the element should be sortable:
handle option to restrict drag start to the specified element:
forcePlaceholderSize option to true, forces the placeholder to have a height:
acceptFrom instead. The
connectWith option allows you to create a connected lists:
acceptFrom option to restrict which sortable's items will be accepted by this sortable.
acceptFrom accepts a space separated list of selectors or
false to disabling accepting items. This is an alternative to connectWith and should not be used together.
If you want to be able to move items between to sortables, the
acceptFrom option must be present on both of them.
placeholder option to specify the markup of the placeholder:
hoverClass option to apply css classes to the hovered element rather than relying on
:hover. This can eliminate some potential drag and drop issues where another element thinks it is being hovered over.
maxItems option to restrict the number of items that can be added to a sortable from a connected sortable.
maxItems should always be combined with the
items option. Make sure
items does not match placeholder and other options, so that they are not counted.
copy option to duplicate the element on drag. The original element will remain in the same position.
orientation option to specify the orientation of your list and fix incorrect hover behaviour. Defaults to
You can provide a
function that will be applied to every item in the
items array (see serialize). The function receives two arguments:
sortableContainer: Element. This function can be used to change the output for the items. Defaults to
You can provide a
function that will be applied to the
container object (see serialize). The function receives one argument:
serializedContainer: object. This function can be used to change the output for the container. Defaults to
You can provide a function as a
customDragImage property on the options object which will be used to create the item and position of the drag image (the half transparent item you see when dragging an element).
The function gets three parameters, the dragged element, an offset object with the offset values for the offset of the item and the
dragstart event. The function MUST return an object with an
element property with an html element as well as a
posY property with has the x and y offset for the dragImage.
;// elementOffset object that is received in the customDragImage functionleft: rectleft + windowscrollXright: rectright + windowscrollXtop: recttop + windowscrollYbottom: rectbottom + windowscrollY
To remove the sortable functionality completely:
To disable the sortable temporarily:
To enable a disabled sortable:
You can easily serialize a sortable using the
serialize command. If you provided an
containerSerializer function in the options object, they will be applied to the
container object and the
items objects before they are returned.
;// You will receive an object in the following formatcontainer:node: sortableContaineritemCount: itemslengthitems:parent: sortableContainernode: itemhtml: itemouterHTMLindex:……
When you add a new item to a sortable, it will not automatically be a draggable item, so you will need to reinit the sortable. Your previously added options will be preserved.
Sorting table rows
- Initialize plugin on
tbodyelement (browsers automatically add
tbodyif you don't)
- Keep in mind that different browsers may display different drag images of the row during the drag action. Webkit browsers seem to hide entire contents of
tdcell if there are any inline elements inside the
td. This may or may not be fixed by setting the
- If you add a custom
placeholderyou must use a
placeholder: "<tr><td colspan="3">The row will appear here</td></tr>", otherwise you will only be able to drop items when hovering the first column.
Contributions are always welcome. Please check out the contribution guidelines to make it fast & easy for us to merge your PR.
Polyfills: Facing towards the future instead of the past
Small and fast package for modern browsers
While a backwards facing approach penalises modern browsers by making them download huge files, we prefer to ship a small package and have outdated browser bear the penalty of the polyfill. An additional benefit is that you might polyfill those features in any case so you don't have any additional load.
Contribution friendly code base
Helps browser optimisation
Browser try to performance optimise language features as much as possible. Working around the language to make code work in outdated browser may actually work against this.
We recommend using the Financial Times Polyfill Service which will polyfill only the necessary features for browsers that need a polyfill. It is basically a no-config, easy solution.
- Dragstart not working on buttons
Dragstart event does not fire on
buttonelements. This effectively disables drag and drop for button elements. See https://caniuse.com/#feat=dragndrop in the known issues section.