51

Is there a way to make a <div> container resizeable with drag & drop?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Chris
  • 9,209
  • 16
  • 58
  • 74

5 Answers5

78

The best method would be to use CSS3. It supported by at least Webkit and Gecko.

According to the w3c spec:

div.my_class {
    resize:both;
    overflow:auto; /* something other than visible */
}

Webkit and Firefox do not interpret the specs the same way. In Webkit the size is limited to the width and height set. There's another question: How can I use CSS to make an element resizable to a dimension smaller than the initial one? concerning this.

Community
  • 1
  • 1
Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
  • 1
    that only allows you to resize from a corner right? – Winnemucca Oct 17 '17 at 16:22
  • @Irfan it is possible like below. .resizable-content { min-height: 30px; min-width: 30px; resize: both; overflow: auto; max-height: fit-content; max-width: fit-content; } – sushmitha shenoy Mar 10 '18 at 11:36
  • 3
    That resize "grabber", in the bottom-right corner, is [way to small in Chromium 69 on a 4K monitor](https://bugs.chromium.org/p/chromium/issues/detail?id=884575) and its style isn't accessible via CSS; you can't scale it larger (at the time of this writing). – Lonnie Best Sep 17 '18 at 00:52
15

div {
  border: 1px solid black;
}

.resizable-content {
  min-height: 30px;
  min-width: 30px;
  resize: both;
  overflow: auto;
  max-height: fit-content;
  max-width: fit-content;
}
<div class="resizable-content">Resize Me!</div>
Seph Reed
  • 8,797
  • 11
  • 60
  • 125
7

The problem with the CSS3-only method is that only the bottom-right-hand corner of the div becomes draggable. Users will almost surely want to resize the div from any of the borders, not just the bottom-right-hand corner.

After wasting a bunch of time trying to accomplish this via copying code-snippets from Stack Overflow, I would highly recommend just using the excellent InteractJS JavaScript library in your project. It allows to you easily create a resizable (and draggable) div that can be resized from all sides.

James
  • 1,394
  • 2
  • 21
  • 31
0

if you need to execute some function doOnResize(tag) for every tag (also the <div>) among the array of mustberesizeable tags, you could simple copy this array to window's one:

window[WIN_RESIZED] = [] // init the window's array
for (var i in tags) {      
  window[WIN_RESIZED].push(tags[i])
}

and after that set

window.addEventListener('resize', function(e){
  for (var i in window[WIN_RESIZED]) {
    doOnResize(window[WIN_RESIZED][i])
  }
})

where somewehere in the beginning must be written

const WIN_RESIZED = 'move_resized_divs'

with arbitrary name like 'move_resized_divs'

Leon Rom
  • 537
  • 4
  • 6
0

let root = document.documentElement;
        let spliter = document.querySelector('.spliter-div');
        let rowDiv = document.querySelector('.row-divs');
        let cd1 = document.getElementById('cd-1');
        var isDown = false;
        var isHover = false;
        var minWidth = 127;
        var maxWidth = 600;

        function setPosition() {
            var cl = this.document.querySelector('.col-div');
            if (cl) {
                root.style.setProperty('--m-x', (cl.offsetWidth + 3.5) + 'px');
            }
            minWidth = (parseInt(rowDiv.clientWidth / 10) * 2) + 22;
            maxWidth = parseInt(rowDiv.clientWidth - minWidth);
        }
        function moveTo(e) {
            if (e.clientX > minWidth && e.clientX < maxWidth) {
                if (cd1.classList.contains('col-div-flex')) {
                    cd1.classList.remove('col-div-flex');
                }
                cd1.style.width = e.clientX  + 'px';
                root.style.setProperty('--m-x', (e.clientX + 9.5) + 'px');
            }
        }
        window.addEventListener('DOMContentLoaded', function (e) {
            setPosition();
        });
        window.addEventListener('resize', function (e) {
            setPosition();
        });
        root.addEventListener('mousedown', function (e) {
            if (isHover) {
                isDown = true;
            }
        }, true);
        document.addEventListener('mouseup', function (e) {
            isDown = false;
            if (isHover) {
                //...
            }
        }, true);
        document.addEventListener('mousemove', function (e) {
            if (isDown) {
                moveTo(e);
            }
        });
        spliter.addEventListener('mouseenter', function (e) {
            isHover = true;
            spliter.style.cursor = 'col-resize';
        });
        spliter.addEventListener('mouseout', function (e) {
            isHover = false;
        });
:root{
    --m-x: 0px;
}

html,
body{
    height: 100% ;
    width: 100% ;
    margin: 0 ;
    overflow: hidden ;
}

body{
    margin-bottom: 60px ;
}

.container-divs{
    display: flex ;
    flex: 1 1 auto ;
    height: 100% ;
    width: 100% ;
}

.row-divs{
    display: flex ;
    width: 100% ;
}

.col-div{
    margin: 3px ;
    padding: 3px ;
    min-width: 20% ;
    max-width: 80% ;
}

.col-div-flex{
    flex: 1 0 0%;
}

.border-div{
    border: 1px #a3a3a3 ridge;
    border-radius: 9px;
}

.spliter-div{
    width: 5px ;
    height: 96% ;
    margin: 3px 0;
    background: #9a969676;
    position: absolute;
    left: var(--m-x);
    margin-top: 9px ;
    cursor: col-resize;
}
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Divs - Resizeable</title>
</head>
<body>
    <div class="container-divs">
        <div class="row-divs">
            <div id="cd-1" class="col-div col-div-flex border-div" style="background-color:#d5ff00f7">
            </div>
            <div class="spliter-div"></div>
            <div id="cd-2" class="col-div col-div-flex border-div" style="background-color: #6719b5e2">
            </div>
        </div>
    </div>
</body>
</html>