Sortable icon indicating copy to clipboard operation
Sortable copied to clipboard

[bug] Using any CSS transformation in an ancestor of the sortable element causes the drag preview to be left behind on scroll

Open camyyssa opened this issue 3 years ago • 2 comments

Describe the bug

Assigning a css transform to any parent of the sortable element will cause the drag preview to stay behind when scrolling (by dragging the element to the top or bottom, by using the scroll gesture on the touchpad, or by using a mouse scroll wheel - the last one I assume, but I don't have a mouse to test)

To Reproduce

Steps to reproduce the behavior:

  1. Create container to the scrollable element that contains any CSS transform, e.g. transform: rotate(0). Sortable needs to rely on Autoscroll, rather than the default behaviour of the browser -> make sure Sortable is initialized with forceFallback: true
  2. Pick any item in the list
  3. Move to the bottom of the list and trigger the auto-scrolling behaviour. 3b. Scroll down using a touchpad gesture
  4. Observed the drag preview of the item moves away from the mouse with scrolling

Expected behavior 4. Expected the drag preview stays under the mouse while the dom underneath scrolls

Screen Shot 2021-11-11 at 22 33 42

Information

sortablejs = 1.14.0

Additional context In our code we use a transform-Y to move the view down, and make place for a drawer at the top that the user can either open or close. Not being able to use any transformations makes finding a solution for our use-case hard. At a user level, the bug makes the UI look broken.

Reproduction This bin has the code bellow if still accessible: https://jsbin.com/disatokeci/edit?html,css,js,output

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
  
  
<!-- Latest Sortable -->
<script src="https://raw.githack.com/SortableJS/Sortable/master/Sortable.js"></script>
  
  
<!-- Simple List -->
<div class="container">
  <div id="simpleList" class="list-group"></div>
</div>
Sortable.create(simpleList, {ghostClass: 'is-dragged',
        dragClass: 'drag-preview',
        animation: 400,
        scroll: true,
        forceFallback: true,
        scrollSensitivity: 50,
        scrollSpeed: 20, });

// Generate 100 items
simpleList.innerHTML = Array.apply(null,  new Array(100)).map(function (v, i) {
  return '<div class="list-group-item">item ' +
    (i + 1) +
    '</div>';
}).join('');
/* ghostClass */
.ghost {
  opacity: .5;
  color: #C8EBFB !important;
  background: #C8EBFB !important;
}

.drag-preview {
    background: pink;
}

.container {
  /* -----> Assigning any of these values to transform for the container causes the drag element to be left behind during scroll */
  /*transform: translateX(0) translateY(0px) rotate(0) skewX(0) skewY(0) scaleX(1) scaleY(1)*/
  transform: rotate(0)
}

body {
  padding: 20px;
}
.list-group-item {
  cursor: move;
}

camyyssa avatar Nov 11 '21 21:11 camyyssa

Yes, I was able to see it happening in the jsbin shared, but only scrolling up. So I first scrolled down the list a little bit, then I dragged an item upwards.

https://user-images.githubusercontent.com/19625575/168673612-b0fd843a-5e4c-4c49-aba4-9b5671fa4be3.mp4

fterradev avatar May 16 '22 20:05 fterradev

BTW for whatever reason it doesn't happen if we add a style like this:

.list-group {
  height: 400px;
  overflow: auto;
}

I added it because I was trying to see the issue when dragging the item downwards, but it actually "fixed" the issue.

https://jsbin.com/jemoqicegu/edit?html,css,js,output

fterradev avatar May 16 '22 20:05 fterradev