Responsive & Drag-And-Drop Grid Layout with jQuery – gridstack.js

Demo    Download
Responsive & Fluid Drag-and-Drop Grid Layout with jQuery - gridstack.js
File Size: 14.35 KB
Views Total: 1751 views
Last Update:April 13, 2021
Publish Date: November 10, 2014
Official Website: Go to website
License: MIT
Plugin Author: gridstack

Gridstack.js is a vanilla JavaScript Drag-And-Drop Grid Layout plugin inspired by Gridster that allows you to dynamically and responsively rearrange grid items through drag and drop.
Like Mobile friendly use with Javascript library (with Typescript bindings) for dashboard layout and creation. Make with drag and drop, multi-column and responsive dashboard, responsive with bootstrap v4 friendly layouts. It also with multiple build great with React, Angular, Knockout.js, Ember and others. Includes Typescript defines.

Note: The library now works as a Vanilla JavaScript plugin and the next scroll down jQuery Plugin.

Basic Usage (Vanilla JS Version):

1. Install & Download the package.

# Yarn
$ yarn add gridstack

$ npm install gridstack --save

2. Include the necessary JavaScript and CSS files on the page.

<link rel="stylesheet" href="" />
<script src=""></script>

3. Insert optional grid items to the Grid Stack container.

<div class="grid-stack">
  <div class="grid-stack-item">
    <div class="grid-stack-item-content">Item 1</div>
  <div class="grid-stack-item" data-gs-width="2">
    <div class="grid-stack-item-content">Item 2 wider</div>

4. Initialize the plugin and done.

var grid = GridStack.init();

5. All options, methods, and events are same as the jQuery version. Keep scrolling down to learn more.

Basic Usage (jQuery Version):

1. Include jQuery library and other required resources in the the document.

  • jQuery
  • jQuery UI
  • jQuery UI Touch Punch: for touch support (OPTIONAL)
  • gridstack.poly.js: for IE and older browsers (OPTIONAL)
<!-- Local -->
<link href="/path/to/gridstack.css" rel="stylesheet" />
<!-- Or From A CDN -->
<link rel="stylesheet" href="" />

2. Include the jQuery Gridstack.js plugin and other required resources at the end of the document.

<!-- Dependencies -->
<script src="/path/to/cdn/jquery.min.js"></script>
<script src="/path/to/cdn/jquery-ui.min.js"></script>
<script src="/path/to/cdn/jquery.ui.touch-punch.min.js"></script>

<!-- jQuery Gridstack.js -->
<script src="gridstack.all.js"></script>
<!-- Or from a CDN -->
<script src=""></script>
<!-- Polyfill for old IE -->
<script src="gridstack.poly.js"></script>

3. Create a sample draggable grid layout as follows.

data-gs-animate: turns animation on (for grid)
data-gs-column: amount of columns (for grid)
data-gs-max-row: maximum rows amount, defaults to 0 (for grid)
data-gs-current-height: current rows amount (for grid)
data-gs-id: unique ID (for item)
data-gs-x, data-gs-y: element position (for item)
data-gs-width, data-gs-height: element size (for item)
data-gs-max-width, data-gs-min-width, data-gs-max-height,data-gs-min-height: element constraints (for item)
data-gs-no-resize: disable element resizing (for item)
data-gs-no-move: disable element moving (for item)
data-gs-auto-position: tells to ignore data-gs-x and data-gs-y attributes and to place element to the first available position (for item)
data-gs-locked: the widget will be locked. It means another widgets couldn't move it during dragging or resizing. The widget is still can be dragged or resized. You need to add data-gs-no-resize and data-gs-no-move attributes to completely lock the widget (for item)
data-gs-resize-handles: resize handles (for item)
<div class="grid-stack" data-gs-width="12">
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="4">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="0" data-gs-width="2" data-gs-height="2" data-gs-min-width="2" data-gs-no-resize="yes">
    <div class="grid-stack-item-content"> <span class="fa fa-hand-o-up"></span> Drag me! </div>
  <div class="grid-stack-item" data-gs-x="10" data-gs-y="0" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="4" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="2" data-gs-y="4" data-gs-width="2" data-gs-height="4">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="4" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="4" data-gs-y="6" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  <div class="grid-stack-item" data-gs-x="10" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>

4. Call the plugin and create a responsive & fluid 12 columns grid layout.

$(function () {
    column: 12

5. All possible options and defaults available.


  // accept widgets dragged from other grids or from outside
  // true (uses '.grid-stack-item' class filter) or false
  // string for explicit class name
  // function (i: number, element: Element): boolean
  acceptWidgets: false,

  // turns animation on
  animate: false,

  // amount of columns
  column: 12,

  // max/min number of rows
  maxRow: 0,
  minRow: 0

  // maximum rows amount
  height: 0, 

  // widget class
  itemClass: 'grid-stack-item',

  // class for placeholder
  placeholderClass: 'grid-stack-placeholder',

  // text for placeholder
  placeholderText: '',

  // draggable handle selector
  handle: '.grid-stack-item-content',

  // class for handle
  handleClass: null,

  // allow for selecting older behavior (adding STYLE element to HEAD element instead of parentNode)
  styleInHead: false,

  // one cell height
  cellHeight: 60,

  // vertical gap size
  verticalMargin: 20,

  // unit
  verticalMarginUnit: 'px',
  cellHeightUnit: 'px',

  // if false it tells to do not initialize existing items
  auto: true,
  // minimal width.
  minWidth: 768,

  // class set on grid when in one column mode
  oneColumnModeClass: 'grid-stack-one-column-mode',

  // set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column layouts during sorting. This enables you to have custom 1 column layout that differ from the rest.
  oneColumnModeDomSort: false,

  // enable floating widgets
  float: false,

  // makes grid static
  staticGrid: false,

  // if true the resizing handles are shown even the user is not hovering over the widget
  alwaysShowResizeHandle: false,

  // allows to owerride jQuery UI draggable options
  draggable: {handle: '.grid-stack-item-content', scroll: true, appendTo: 'body', containment: null},

  // let user drag nested grid items out of a parent or not
  dragOut: false,

  // allows to owerride jQuery UI resizable options
  resizable: {autoHide: true, handles: 'se'},

  // disallows dragging of widgets
  disableDrag: false

  // disallows resizing of widgets
  disableResize: false,

  // if `true` turns grid to RTL. 
  // Possible values are `true`, `false`, `'auto'`
  rtl: 'auto',

  // if `true` widgets could be removed by dragging outside of the grid
  removable: false,

  // time in milliseconds before widget is being removed while dragging outside of the grid
  removeTimeout: 2000,

  // CSS class when in one column mode
  disableOneColumnMode: 'grid-stack-one-column-mode',

  // class that implement drag'n'drop functionallity for gridstack
  ddPlugin: null


6. API methods methods.

// Creates a new widget.
grid.addWidget(el, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id);

// Initailizes batch up<a href="">date</a>s. 
// You will see no changes until commit method is called.

// Relayout grid items to reclaim any empty space.

// Gets current cell height.

// Update current cell height.
// grid.cell_height(grid.cell_width() * 1.2);
grid.cellHeight(val, noUpdate);

// Gets current cell width.

// Returns current vertical margin value.

// value - new vertical margin value.
// noUpdate - if true, styles will not be updated.
grid.verticalMargin(value, noUpdate)

// Finishes batch updates. Updates DOM nodes. You must call it after batch_update.

// set/get floating widgets

// Disables / enables widgets moving/resizing.
grid.movable('.grid-stack-item', false);
grid.resizable('.grid-stack-item', true); 

// Get the position of the cell under a pixel on screen.
// position - the position of the pixel to resolve in absolute coordinates, as an object with top and leftproperties
// useOffset - if true, value will be based on offset vs position (Optional. Default false). Useful when grid is within position: relative element
// Returns an object with properties x and y i.e. the column and row in the grid.
grid.getCellFromPixel(position, useOffset);

// Checks if specified area is empty.
grid.isAreaEmpty(x, y, width, height);

// Locks/unlocks widget.
// el - widget to modify.
// val - if true widget will be locked.
grid.locked(el, val);

// Make new widgets after new items are appended to the grid.

// Set the minWidth/maxWidth for a widget.
grid.minWidth(el, val);
grid.maxWidth(el, val);

// Set the minHeight/maxWidth for a widget.
grid.minHeight(el, val);
grid.maxHeight(el, val);

// Removes widget from the grid.
// detachNode - if false node won't be removed from the DOM
grid.removeWidget(el, detachNode);

// Removes all widgets from the grid.
// detachNode - if false node won't be removed from the DOM

// Changes widget size
grid.resize(el, width, height);

// Changes widget position
grid.move(el, x, y);

// Enables/Disables resizing.
grid.resizable(el, val);

// Enables/Disables moving.
grid.movable(el, val);

// Updates widget position/size.
grid.update(el, x, y, width, height);

// Returns true if the height of the grid will be less the vertical constraint. Always returns true if grid doesn't have height constraint.
grid.willItFit(x, y, width, height, autoPosition);

// Toggle the grid animation state.
// doAnimate - if true the grid will animate.
grid.set<a href="">Animation</a>(doAnimate);

// Modify number of columns in the grid
// doNotPropagate - if true existing widgets will not be updated.
// NOTE: Use column() instead in v1.0+
grid.setColumn(column, doNotPropagate);

// Update widget position/size.

// Toggle the grid static state
// staticValue - if true the grid becomes static.
grid.update(el, x, y, width, height));

// Destroy the instance
// detachGrid - if false nodes and grid will not be removed from the DOM

// Enables/disables the plugin

// Enables/disables widget moving. includeNewWidgets will force new widgets to be draggable as per doEnable's value by changing the disableDrag grid option.
grid.enableMove(doEnable, includeNewWidgets);

// Enables/disables widget resizing. includeNewWidgets will force new widgets to be resizable as per doEnable's value by changing the disableResize grid option. 
grid.enableResize(doEnable, includeNewWidgets);

7. Event listeners available.

$('.grid-stack').on('added', function(event, items) {
  // after new items are added

$('.grid-stack').on('change', function(event, items) {
  // fired on change

$('.grid-stack').on('disable', function(event) {
  // var grid =;

$('.grid-stack').on('dragstart', function(event, ui) {
  // var grid = this;
  // var element =;

$('.grid-stack').on('dragstop',  function(event, ui) {
  // var grid = this;
  // var element =;

$('.grid-stack').on('dropped',  function(event, previousWidget, newWidget) {
  // after dropped

$('.grid-stack').on('enable',  function(event) {
  // var grid =;

$('.grid-stack').on('removed',  function(event, items) {
  // after removed

$('.grid-stack').on('resizestart',  function(event, ui) {
  // var grid = this;
  // var element =;

$('.grid-stack').on('gsresizestop',  function(event, items) {
  // on stop resizing


List Of Version :
  • v4.2.0
  • v4.1.0
  • v4.0.3
  • v4.0.2
  • v4.0.1
  • v4.0.0
  • v3.3.0
  • v3.2.0
  • v3.1.5
  • v3.1.4
  • v3.1.3
  • v3.1.2
  • v3.1.1
  • v3.1.0
  • v3.0.0
  • v2.2.0
  • v2.1.0
  • v2.0.2
  • v2.0.1
  • v2.0.0
  • v2.0.0-rc2
  • v2.0.0-rc
  • v1.2.1
  • v1.2.0
  • v1.1.2
  • v1.1.1
  • v1.1.0
  • v1.0.0
  • v0.6.4
  • v0.6.3

Nola Arney

Nola Arney is a full stack web developer who has Author at jQuerypost. Her ambition for development is only matched by his desire to find the perfect meme for every occasion.