Reputation: 43629
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
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
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
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
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
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
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
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
Reputation: 20415
Use jQuery UI with the ghost option:
$( "#resizable" ).resizable({ ghost: true });
Upvotes: 6
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