jovan jovan - 2 months ago 54
CSS Question

Drag-and-drop from div with scrollbars - overflow-y scroll VS overflow-x visible

I've set up jQuery drag-and-drop from a div to another div and it works fine.

However, the source div sometimes exceeds the screen's height so I needed to add a vertical scrollbar to it. Here's where I run into trouble with the infamous overflow-y issue.

The div needs to have overflow-x: visible in order for the dragged elements to be visible as they are moved to the target div. But, when I add overflow-y: scroll or overflow-y: auto to the source div, suddenly overflow-x doesn't work anymore.

I have been to W3 and a few StackOverflow questions, and I realise this is not a bug but intended behavior (although WHY this was intended is beyond me). However, I haven't found a solution that works for me.

I've tried adding a wrapper div to the source div like some answers suggested, and then doing the following:

.wrapper {
width: 100px;
position: absolute;
top: 4vw;
left: 0;
bottom: 4vw;
overflow-y: auto;

.source {
position: relative;
overflow: visible;
z-index: 2;

<div class="wrapper">
<div class="source">
<!-- draggable elements go here -->

<div class="target">
<!-- draggable elements drop here -->

But, despite the source div's overflow being OK now, the wrapper still hides the horizontal overflow. I suppose I could increase the width of the wrapper to full screen and make the background invisible and make everything else on screen have a higher z-index in order to not be behind the wrapper, but that seems like a ridiculously bad solution for such a simple issue.

Can anyone help me here?

If a CSS solution isn't practical, can anyone offer some piece of Javascript that might resolve the problem?

Code sample: jsfiddle


Please check the following. If you want to drag elements and "drop" them on your battle positions, you may want to use helper: "clone" in combination with appendTo: "body" or any other selector which is where your items will be dropped. I've also added containment: 'window' and scroll: false (not too sure if this last one is what you want).

function make_draggable(elem){
        revert: "invalid",
        cursor: "move",
        helper: 'clone',
        appendTo: 'body',
                    containment: 'window',
        scroll: false,

There's also been a few CSS fixes so your styles still apply on the draggable clones and your body actually covers the full area (since your only child is positionated absolute, so we need to force body to cover the full height/width)

EDIT: Adding custom class and removing it on the original element so you can show feedback to the user.