Take the 2-minute tour ×

I have a draggable element that has containment set as parent. This works great but the div content can change making it taller. Is there anyway to trigger the drag event that will ensure it doesnt move from inside its parent. As right now it can overlap the parent until it is dragged then the containment kicks in.

Best Regards Mark

share|improve this question
add comment

3 Answers

I've implemented a small plugin that does what you want. It can enforce the containment after the draggable changes size and it even works while you're in the middle of a drag. I've tested it with jQuery UI 1.8.6 and jQuery 1.4.3 but it might break with past or future releases since it has to use internal methods.

Working Demo


Full Source


 * jQuery UI RefreshContainment v0.1
 * A plugin for jQuery UI's Draggable. It adds a refreshContainment method to
 * every draggable which allows you to use the containment option on draggables
 * with dynamically changing sizes.
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 *  jquery.ui.draggable.js

(function ($){
  var $window = $(window);

  // We need to know the location of the mouse so that we can use it to
  // refresh the containment at any time.

  $window.data("refreshContainment", {mousePosition: {pageX: 0, pageY: 0}});
  $window.mousemove(function (event) {
    $window.data("refreshContainment", {
      mousePosition: {pageX: event.pageX, pageY: event.pageY}

  // Extend draggable with the proxy pattern.
  var proxied = $.fn.draggable;
  $.fn.draggable = (function (method){
    if (method === "refreshContainment") {
      this.each(function (){
        var inst = $(this).data("draggable");

        // Check if the draggable is already being dragged.
        var isDragging = inst.helper && inst.helper.is(".ui-draggable-dragging");

        // We are going to use the existing _mouseStart method to take care of
        // refreshing the containtment but, since we don't actually intend to
        // emulate a true _mouseStart, we have to avoid any extraneous
        // operations like the drag/drop manager and event triggering.
        // So we save the original member values and replace them with dummies.
        var ddmanager = $.ui.ddmanager;
        $.ui.ddmanager = null;
        var trigger = inst._trigger;
        inst._trigger = function () { return true; }

        var mousePosition = $window.data("refreshContainment").mousePosition;
        var fakeEvent = {
          pageX: mousePosition.pageX, pageY: mousePosition.pageY

        // Return those extraneous members back to the original values.
        inst._trigger = trigger;
        $.ui.ddmanager = ddmanager;

        // Clear the drag, unless it was already being dragged.
        if (!isDragging) {
      return this;
    else {
      // Delegate all other calls to the actual draggable implemenation.
      return proxied.apply(this, arguments);


<!DOCTYPE html>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>

  #container { width: 20em; height: 20em; border: 0.5em solid black; }
  .draggable { width: 5em; height: 5em; border: 0.2em solid black; position: absolute; }
  #one { background-color: #F55; }
  #two { background-color: #5F5; }
  <div id="container">
    <div class="draggable" id="one">drag me</div>
    <div class="draggable" id="two">drag me</div>

Demo JavaScript

var draggables = $('.draggable');

draggables.draggable({containment: 'parent', stack: draggables});

var resizeDraggables = function (){
    each(function (){
      var size = 5 + Math.random() * 5;
      size = size.toString() + "em";
      $(this).css({width: size, height: size});


setInterval(resizeDraggables, 2000);
share|improve this answer
Modified a little, to prevent errors when the mouse-over hasn't occured yet: jsbin.com/uvino4/5/edit –  Chris van de Steeg Sep 17 '12 at 12:41
@ChrisvandeSteeg Thanks for the fix! –  brianpeiris Sep 17 '12 at 14:47
Great fix, Brian. One thing I had to do to get it to work was to change $(window) to $(document) for the "mousemove" listener. "mousemove" doesn't fire on "window" in some browsers (IE8 in my case). Using document instead will work in all browsers. –  rickdmer Jun 19 '13 at 14:21
add comment

Does this work?

$("#yourcontainment").bind("resizestop", function () {
  $(".yourdraggables").draggable("option", "containment", $("#yourcontainment"));

You have to trigger the "resizestop" event if you do not use jQuery UI's resizable.

share|improve this answer
Thank you! It's also worth noting that for this to work, the containment element apparently has to be an actual element. If you have containment: "parent", this doesn't work even though the $(".yourdraggables") selector would include the parent element. –  tsiki Jun 20 '13 at 21:06
add comment

Because you are modifying the [contained] elements size, you must implement your own handler for the results. jQuery knows what to do during drag, but during a resize there are many possible behaviors:

  • prevent resize of the contained
  • element move the internal elements (which direction)
  • delete elements

One can imagine a range of fictitious scenarios for different UI constraints.

Just create a PostionValidator() method for all objects of the contained class, and execute it after calling the modification method.

share|improve this answer
add comment

Your Answer


