Why is drag & drop so much smoother when adding "overflow: auto"?
The default value for overflow is "visible", meaning that the overflow is not clipped. It renders outside the element's box.
The value auto means that if overflow is clipped, a scroll-bar should be added to see the rest of the content.
The smoothness effect that you refer to is simple that in default overflow, rendering outside the element's box will probably be slower/jumpier than when set to auto which moves the rendering into the actual element. This was especially noticeable for me in firefox looking at your fiddle example after moving all the elements to one column then trying to move them back.
Surprisingly in IE11, there was no noticeable difference between auto/default that I could see.
Please Read: Official W3 Documentation for Visual Effects
You must think about the HTML elements. Every HTML element is wrapped within its own 'box'. For each box, you can set its CSS properties like height
, width
, margin
, padding
, and so on. Each box is designed to expand with its content, even when you give it a set height
. This state is known as overflow: visible;
and is the default for every element.
In your case, you are dragging elements within an element to another element. Let's break this down a little. Before we begin dragging, our element lives within another element, inheriting its properties as well. The child element will do its best to fit within the parent element. When we drag the child element, jQuery is allowing the child element to be free from the parent element, and it will no longer inherit the parent element's properties. The child element's content will now expand to its own CSS properties until you drag it into another parent element, at which point it will inherit the new parent's properties.
In the same sense that the child is affected by the parent, the parent can be affected by the child element as well. After all, its default is overflow: visible;
and wants to show all the content that is contained within it. So if the parent is 100px
in width
and the child is 200px
, the child will be visible for 100 px
outside the parent's original size.
As designers want to contain our elements to a fixed size, whether it is a px
value or %
fraction based on the parent element, so we need a way to prevent child elements overflowing outside of our parent element. This is were CSS overflow: hidden;
, scroll;
, and and auto;
comes into play. I do want to note that there are overflow-x
and overflow-y
properties, however, I won't cover them too much as they are self-explanatory. Overflow: hidden;
will simply hide the content that would overflow outside the parent element. This option will give no scrollbars for the user to view the overflowed content. So Overflow: Scroll
shows the scrolling bars so that the user can scroll and see hidden overflowed content within the parent element. This option will always show vertical and horizontal scrollbars. Note: This is why there are overflow-x
and overflow-y
properties, however with overflow: auto;
, they are not necessary.
Overflow: auto;
is the solution for having only the necessary scrollbars for the content, and as a bonus, if the content does not overflow, no scrollbars are shown. So when we look at your div.sortobject
, without overflow: auto;
, it will attempt to visually stretch out to fit it's child elements. When you begin to drag elements around, the potential parent divs are overflowing visually trying to resize both for the child element and the jQuery helper element, the element that shows the user where to drop content. Setting overflow: auto;
will cause the parent element to always retain its set width
and height
, so that when you drag your child element, it will appear smoothly as no potential parent elements are resizing. jQuery loves to calculate current exact dimensions of the elements it affects, and will also improve the animation as well.
I hope this gave some insight.
In the overflow-auto, I noticed there is a horizontal scroll bar in some of your boxes. If you take off any overflow, the div width will expand due to the content contained within them. When you get fatter divs, you'll get mixed div widths, and can cause quirky div placements when you drag them within a parent container. Think of a bucket with fat apples and small apples, versus a bucket with apples of all the same size; the position of the apples will be scrunched up differently between the two.
Bucket of fat apples with small apples: (div width of different sizes)
If you don't believe me that the div's are fat, you made the under lay of the divs the same size, but open up your link without the overflow = auto, you'll notice your images go over the right hand side of the border.
Bucket of apples of equal size (div width of same sizes)
With overflow set to auto, if you get beyond a certain width, the scroll bar will appear, and the width of the content will flow through, not changing the width of the div; so nothing gets quirky.