Shamoon
Shamoon

Reputation: 43629

How can I resize a DIV by dragging just ONE side of it?

Let me be more specific... I don't want the DIV to resize WHILE I'm dragging. I want to drag it out (and maybe a vertical line follows my cursor) and when I release, it resizes the div.

Upvotes: 50

Views: 96722

Answers (9)

Deepak Thomas
Deepak Thomas

Reputation: 3535

There is a much simpler way to achieve this. CSS 3 has a resize property to make an HTML element resizeable, while following other CSS properties like min/max widths etc.

.resizeable {
  resize: both;
  overflow: auto;
  border: 2px solid black;
}

For more info, here are the MDN Docs on the resize CSS 3 property.

Upvotes: 21

Monwell Partee
Monwell Partee

Reputation: 718

Pure JS
Live Update
CSS Variable

let dragging = 0,
  body = document.body,
  target = document.getElementById('dragbar');

function clearJSEvents() {
  dragging = 0;
  body.removeEventListener("mousemove", resize);
  body.classList.remove('resizing');
}

function resize(e) {
  if (e.pageX > 400 || e.pageX < 200) {
    return;
  }
  body.style.setProperty("--left-width", e.pageX + 'px');
}

target.onmousedown = function(e) {
  e.preventDefault();
  dragging = 1;
  body.addEventListener('mousemove', resize);
  body.classList.add('resizing');
};

document.onmouseup = function() {
  dragging ? clearJSEvents() : '';
};
body {
  --left-width: 300px;
  padding: 0;
  margin: 0;
}

body.resizing {
  cursor: col-resize;
}

#main,
#sidebar,
#dragbar {
  top: 0;
  height: 100%;
  background: white;
  position: absolute;
}

#sidebar {
  background: #e6e9f0;
  width: var(--left-width);
}

#main {
  right: 0;
  overflow: scroll;
  width: calc(100% - var(--left-width));
}

#main section {
  margin: 20px auto;
  border-radius: 10px;
  background: white;
  height: 100px;
  width: calc(100% - 60px);
  transition: 0.3s ease-in-out 0s;
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
}

#main section:hover {
  box-shadow: 0px 3px 25px rgba(0, 0, 0, 0.2), 0px 0px 0px 1px #A8D1FD;
}

#dragbar {
  right: 0;
  width: 5px;
  opacity: 0;
  cursor: col-resize;
  background: #0099e5;
  transition: 0.3s ease-in-out 0s, opacity 0.3s ease-in-out 0s;
}

#dragbar:hover,
body.resizing #dragbar {
  opacity: 1;
  transition: 0.3s ease-in-out 0s, opacity 0.3s ease-in-out .3s;
}
<body>
  <section id="sidebar">
    <div id="dragbar"></div>
  </section>
  <main id="main">
    <section></section>
    <section></section>
    <section></section>
  </main>
</body>

Upvotes: 17

A. Morel
A. Morel

Reputation: 10384

Here's a slightly different way to do it without float but first with the content changing in real time dynamically ! (This is the best answer)

var dragging = false;

$('#dragbar').mousedown(function(e){
  e.preventDefault();
  dragging = true;
  var side = $('#side');
  $(document).mousemove(function(ex){
    side.css("width", ex.pageX +2);
  });
});

$(document).mouseup(function(e){
  if (dragging) 
  {
    $(document).unbind('mousemove');
    dragging = false;
  }
});
div{
    color: #fff;
    font-family: Tahoma, Verdana, Segoe, sans-serif;
    
}
#container{
    background-color:#2E4272;
    display:flex;
}
#side{
    background-color:#4F628E;
    width: 300px;
    position: relative;
}
#main{
    background-color:#7887AB;
    z-index: 1;
    flex-grow: 1;
}
#dragbar{
   background-color:black;
   height:100%;
   position: absolute;
   top: 0;
   right: 0;
   width: 5px;
   cursor: col-resize;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
    <div id="side">
      Side<br /> Blabla<br /> Blabla<br /> Blabla<br />
      <div id="dragbar"></div>
    </div>
    <div id="main">Dynamically sized content</div>
</div>

Upvotes: 10

Andrei
Andrei

Reputation: 31

I edited solution from the 1st comment but for vertical resizing of blocks

var i = 0;
var dragging = false;
   $('#dragbar').mousedown(function(e){
       e.preventDefault();
       
       dragging = true;
       var main = $('#main');
       var wrapper = $('#wrapper');
       var ghostbar = $('<div>',
                        {id:'ghostbar',
                         css: {
                                width: main.outerWidth(),
                           			top: e.pageY,
                                left: main.offset().left
                               }
                        }).appendTo('#wrapper');
       
        $(document).mousemove(function(e){
          ghostbar.css("top", (e.pageY + 2));
       });
       
    });

   $(document).mouseup(function(e){
       if (dragging) 
       {
           var percentage = ((e.pageY - $('#wrapper').offset().top) / $('#wrapper').height()) * 100;
           var mainPercentage = 100-percentage;  
           
           $('#sidebar').css("height",percentage + "%");
           $('#main').css("height",mainPercentage + "%");
           $('#ghostbar').remove();
           $(document).unbind('mousemove');
           dragging = false;
       }
    });
body,html{width:100%;height:100%;padding:0;margin:0;}
.clearfix:after {
    content: '';
    display: table;
    clear: both;
}
#wrapper {
  width: 600px;
  margin: 50px auto 0 auto;
  height: 300px;
  background: yellow;
}

#main{
   background-color: BurlyWood;
   height:40%;
    width: 100%;
    min-height: 30px;
   max-height: calc(100% - 30px);
}
#sidebar{
  display: flex;
  align-items: flex-end;
   background-color: IndianRed;
   width:100%;
   height:60%;
   overflow-y: hidden;
   min-height: 30px;
   max-height: calc(100% - 30px);
}

#dragbar{
   background-color:black;
   height:3px;
   float: right;
   width: 100%;
   cursor: row-resize;
}
#ghostbar{
  width: 100%;
    height: 3px;
    background-color:#000;
    opacity:0.5;
    position:absolute;
    cursor: col-resize;
    z-index:999}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div class="clearfix" id="wrapper">
  <div id="sidebar">
       <span id="position"></span>
      <div id="dragbar"></div>
  </div>
  <div id="main">  </div>
</div>

Demo: jsfiddle

Upvotes: 3

ckcc
ckcc

Reputation: 271

Been looking to do this, very nice solution by Gaby. Although my requirement was not to have any absolute elements and use percentages instead of pixels, so I've changed Gaby's code a little to cater for this (if anyone is interested)

CSS

#main{
  background-color: BurlyWood;
  float: right;
  height:200px;
  width: 75%;
}
#sidebar{
  background-color: IndianRed;
  width:25%;
  float: left;
  height:200px;
  overflow-y: hidden;
}
#dragbar{
  background-color:black;
  height:100%;
  float: right;
  width: 3px;
  cursor: col-resize;
}
#ghostbar{
  width:3px;
  background-color:#000;
  opacity:0.5;
  position:absolute;
  cursor: col-resize;
  z-index:999
}

JS

var i = 0;
var dragging = false;
$('#dragbar').mousedown(function(e){
   e.preventDefault();

   dragging = true;
   var main = $('#main');
   var ghostbar = $('<div>',
                    {id:'ghostbar',
                     css: {
                            height: main.outerHeight(),
                            top: main.offset().top,
                            left: main.offset().left
                           }
                    }).appendTo('body');

    $(document).mousemove(function(e){
      ghostbar.css("left",e.pageX+2);
   });

});

$(document).mouseup(function(e){
   if (dragging) 
   {
       var percentage = (e.pageX / window.innerWidth) * 100;
       var mainPercentage = 100-percentage;

       $('#console').text("side:" + percentage + " main:" + mainPercentage);

       $('#sidebar').css("width",percentage + "%");
       $('#main').css("width",mainPercentage + "%");
       $('#ghostbar').remove();
       $(document).unbind('mousemove');
       dragging = false;
   }
});

Demo: http://jsfiddle.net/Bek9L/3020/

Upvotes: 27

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196236

Have a look at this example

Html

<div id="sidebar">
     <span id="position"></span>
    <div id="dragbar"></div>
    sidebar
</div>
<div id="main">
    main
</div>

jquery

var dragging = false;
$('#dragbar').mousedown(function(e){
   e.preventDefault();

   dragging = true;
   var main = $('#main');
   var ghostbar = $('<div>',
                    {id:'ghostbar',
                     css: {
                            height: main.outerHeight(),
                            top: main.offset().top,
                            left: main.offset().left
                           }
                    }).appendTo('body');

    $(document).mousemove(function(e){
      ghostbar.css("left",e.pageX+2);
   });
});

$(document).mouseup(function(e){
   if (dragging) 
   {
       $('#sidebar').css("width",e.pageX+2);
       $('#main').css("left",e.pageX+2);
       $('#ghostbar').remove();
       $(document).unbind('mousemove');
       dragging = false;
   }
 });

Demo at http://jsfiddle.net/gaby/Bek9L/1779/

it is an alteration from the code i posted in Emulating frame-resize behavior with divs using jQuery without using jQuery UI?

Upvotes: 43

user686605
user686605

Reputation:

I wrote (most of) this a while back http://jsfiddle.net/ydTCZ/12/. It is for a table, but it would not be hard to adapt it to a div. I show you this because it provides insight into the jQuery required to create a resize effect, thus allowing for complete customization to suit your needs.

Upvotes: 1

Code Maverick
Code Maverick

Reputation: 20415

Use jQuery UI with the ghost option:

See working jsFiddle demo:

$( "#resizable" ).resizable({ ghost: true });

Upvotes: 6

sscirrus
sscirrus

Reputation: 56779

You can find a resizable div here, which provides that feedback but only resizes once you release.

http://jqueryui.com/demos/resizable/#visual-feedback

Upvotes: 1

Related Questions