admin管理员组文章数量:1194611
I am trying to create a layout which allows you to resize the sidebar by dragging one edge of it. This behavior can be seen in CodePen/CodeSandbox, etc.. - you can drag each 'code window' to resize it. I am looking for this same behavior but with the page layout.
What I have come up with allows me to drag to resize, but if there is a lot of content within the 'main' area (area that is not the sidebar) it throws off the drag.
I want to be able to drag all the way to the edge of the screen, regardless of the content within.
I think the best way to show this issue is by a demo:
Original Demo:
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.width = size;
}
/**
* Helpers
*/
sidebar.style.width = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
}
#resizer {
position: relative;
z-index: 2;
width: 18px;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
background: lightblue;
height: 100%;
flex-grow: 1;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
</div>
<div id="resizer"></div>
<div id="main">
<p id="main-content"></p>
</div>
</div>
</div>
I am trying to create a layout which allows you to resize the sidebar by dragging one edge of it. This behavior can be seen in CodePen/CodeSandbox, etc.. - you can drag each 'code window' to resize it. I am looking for this same behavior but with the page layout.
What I have come up with allows me to drag to resize, but if there is a lot of content within the 'main' area (area that is not the sidebar) it throws off the drag.
I want to be able to drag all the way to the edge of the screen, regardless of the content within.
I think the best way to show this issue is by a demo:
Original Demo:
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.width = size;
}
/**
* Helpers
*/
sidebar.style.width = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
}
#resizer {
position: relative;
z-index: 2;
width: 18px;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
background: lightblue;
height: 100%;
flex-grow: 1;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
</div>
<div id="resizer"></div>
<div id="main">
<p id="main-content"></p>
</div>
</div>
</div>
Updated Demo:
After adding buttons, they appear stretched vertically 100%
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.flexBasis = size;
}
/**
* Helpers
*/
sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
min-width: 0;
}
#resizer {
flex-basis: 18px;
position: relative;
z-index: 2;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
flex-basis: 0;
flex-grow: 1;
min-width: 0;
background: lightblue;
height: 100%;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
</div>
<div id="resizer"></div>
<div id="main">
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
<p id="main-content"></p>
</div>
</div>
</div>
Share
Improve this question
edited Apr 2, 2020 at 5:58
Matt Oestreich
asked Apr 1, 2020 at 23:14
Matt OestreichMatt Oestreich
8,5283 gold badges18 silver badges45 bronze badges
1 Answer
Reset to default 28To set a fixed invariable width in Flexbox, use flex-basis
instead of width
. From that fixed size, a flex item can then shrink or grow depending on the available space and the properties of flex-grow
and flex-shrink
.
Furthermore, the default min-width
value of a flex item is auto
. This means that the item cannot have a width smaller than its content size, even when you set its flex-basis
to 0px
. This means that we have to override the default min-width
value to 0px
so that upon dragging the #resizer
element, it can shrink itself completely.
Here's a working example. I merely tweaked your width
property to flex-basis
in both JS and CSS. And then, I also added a min-width
property of 0px
to both #main
and #sidebar
.
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.flexBasis = size;
}
/**
* Helpers
*/
sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
min-width: 0;
}
#resizer {
flex-basis: 18px;
position: relative;
z-index: 2;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
flex-basis: 0;
flex-grow: 1;
min-width: 0;
background: lightblue;
height: 100%;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
</div>
<div id="resizer"></div>
<div id="main">
<p id="main-content"></p>
</div>
</div>
</div>
本文标签: javascriptResizable SidebarDrag To ResizeStack Overflow
版权声明:本文标题:javascript - Resizable Sidebar - Drag To Resize - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738424956a2086070.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论