I am using SortableJS with a flex box positioned grid, and when I enabled animations the whole grid starts to flip out. It seems the animation is causing the items to be pushed to the next row for a brief moment.
Illustration of the problem:

I am using this with the Angular binding, but I think the problem is with Sortable itself.
CSS and markup for the grid (use whatever for the variables):
<ul class="sort-container" ng-sortable="sortable">
<li ng-repeat="suggestion in suggestions">
<span>{{suggestion.name}}</span>
</li>
</ul>
.sort-container {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
position: relative;
width: 100%;
height: 100%;
li {
position: relative;
cursor: move;
list-style: none;
flex: 1;
max-width: calc(16.67% - 1rem);
min-width: calc(16.66% - 1rem);
height: auto;
border: 1px solid black;
padding: 1rem;
margin: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
&:before {
content: '';
float: left;
padding-top: 100%;
}
}
.sortable-ghost {
opacity: 0.4;
background: none;
border: 1px dashed black;
}
}
$scope.sortable = {
animation: 150
};
Any thoughts as to why this is happening? It seems to only occur when both the min-width and max-width properties of the items are set.
No solutions, only disable the animation.
Do you know what the problem is? Is it in sortable's animation code?
The same problem happens without animation actually, it's just a bit less funky because there is no animation. But the elements are still pushed down to the next line, and then back to the previous line.
It seems to happen when hovering over the margin area of the items. The placeholder is dropped at the end of the list in that case, instead of between the items.
@RubaXa have a look at this Plunkr: https://embed.plnkr.co/aiecTBYAioYQ9KJnovny/
Try to move block D between blocks E and F and you will see block D ghost placeholder is moved to the end of the list.
The same is happening without flexbox, with the items as inline-block: https://embed.plnkr.co/dsKzewYwiD2bHsh3sSRX/
And the same was happening in my project with float: left on the items. So it doesn't seem to matter how the items are positioned.
Removing the margins of the items is the only thing that seems to fix it.
I have fixed the margin issue by wrapping the content with a span which contains the margin instead of the list items. However, when enabling the animation, the "flipping" still occurs.
https://plnkr.co/edit/TZcdSG9D8bQoKBO7yXVN?p=preview
Try to move an item to the end of the list first, and then to the back of the one before last row:

Hi Adam, I had the same problem when i was using display:inline-block on list elements.
I've changed it to display:block;float:left and it works.
Hi @rhoman hmm, I think I tried that too, but still wasn't working properly. I'll give it another go tomorrow. Thanks for the tip.
@rhoman yup you're right, it's not flipping out anymore in the following plunkr;
https://plnkr.co/edit/8xFK6lYkuvUEWlGovJ6g?p=preview
However, I still think the plugin should be fixed for cases where you want to use inline-block or flexbox to position your elements.
@rhoman spoke to soon. It still fails with float: left:
https://plnkr.co/edit/1BwGaMFe979Cy4oGcSuW?p=preview

Someone emailed me a simple solution which fixes this issue by specifying forceFallback: true. This is not ideal though, and I still hope this issue can be looked at further.
I think I solved this issue for myself:
In
_onDragOver: function (/**Event*/evt) {
after:
target = _closest(evt.target, options.draggable, el);
I added:
if (!target || target.animated || dragEl.animated) return;
and it seems to be working without flipping (with animation)
Had to fix some js errors after latest change, this would be patch. No idea would it work for someone else and is it 100% ok because didn't get into code too much:
@@ -601,6 +601,7 @@
}
target = _closest(evt.target, options.draggable, el);
+ if (!target || target.animated || dragEl.animated) return;
dragRect = dragEl.getBoundingClientRect();
if (revert) {
@@ -993,16 +994,19 @@
function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) {
if (el) {
ctx = ctx || document;
-
- do {
- if (
- (selector === '>*' && el.parentNode === ctx)
- || _matches(el, selector)
- ) {
- return el;
- }
- }
- while (el = ('host' in el) ? el.host : el.parentNode)
+ try {
+ do {
+ if (
+ (selector === '>*' && el.parentNode === ctx)
+ || _matches(el, selector)
+ ) {
+ return el;
+ }
+ }
+ while (el = ('host' in el) ? el.host : el.parentNode)
+ } catch(e) {
+ return null;
+ }
}
return null;
@@ -1203,7 +1207,7 @@
re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g');
return (
- (tag === '' || el.nodeName.toUpperCase() == tag) &&
+ (tag === '' || (el.nodeName && el.nodeName.toUpperCase() == tag)) &&
(!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length)
);
}
At the moment, the problem is not reproduced.
http://plnkr.co/edit/CoJHi2r07ntZdG7tzmi1?p=preview
http://recordit.co/t2ib5X0V9A
I'll revert the code change and see if it's fixed in our production app
Seems to be fixed now, thanks.