<div id="app"> <div class="resizable-x"> <div class="div0" style="flex: 50%"> <p>div 0</p> </div> <div class="resizer-x"></div> <div class="resizable-y" style="flex: 50%"> <div class="div1" style="flex: 33.33%"> <p>div 1</p> </div> <div class="resizer-y"></div> <div class="div2" style="flex: 66.66%"> <p>div 2</p> </div> </div> </div> </div>
html, body { width: 100vw; height: 100vh; margin: 0; border: 0; padding: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *, *::before, *::after { -webkit-box-sizing: inherit; -moz-box-sizing: inherit; box-sizing: inherit; } #app { width: 100%; height: 100%; font-family: Arial, Helvetica, sans-serif; } .resizable-x, .resizable-y { display: flex; overflow: hidden; } .resizable-x { height: 100%; } .resizable-y { flex-direction: column; } .resizer-x, .resizer-y { position: relative; display: flex; justify-content: center; align-items: center; background: black; padding: 4px; } .resizer-x { z-index: 2; cursor: col-resize; } .resizer-x::before, .resizer-x::after { content: ""; width: 2px; height: 16px; margin: 2px; background: lightgray; } .resizer-y { z-index: 1; cursor: row-resize; flex-direction: column; } .resizer-y::before, .resizer-y::after { content: ""; width: 16px; height: 2px; margin: 2px; background: lightgray; } .div0, .div1, .div2 { overflow: hidden; } .div0 { background: dodgerblue; } .div1 { background: pink; } .div2 { background: gold; } .div0 p, .div1 p, .div2 p { font-size: 2rem; margin-left: 1em; text-transform: uppercase; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; background: transparent; }
(function () { "use strict"; // horizontal direction (function resizableX() { const resizer = document.querySelector(".resizer-x"); resizer.addEventListener("mousedown", onmousedown); resizer.addEventListener("touchstart", ontouchstart); // for mobile function ontouchstart(e) { e.preventDefault(); resizer.addEventListener("touchmove", ontouchmove); resizer.addEventListener("touchend", ontouchend); } function ontouchmove(e) { e.preventDefault(); const clientX = e.touches[0].clientX; const deltaX = clientX - (resizer._clientX || clientX); resizer._clientX = clientX; const l = resizer.previousElementSibling; const r = resizer.nextElementSibling; // LEFT if (deltaX < 0) { const w = Math.round( parseInt(getComputedStyle(l).width) + deltaX ); l.style.flex = `0 ${w < 10 ? 0 : w}px`; r.style.flex = "1 0"; } // RIGHT if (deltaX > 0) { const w = Math.round( parseInt(getComputedStyle(r).width) - deltaX ); r.style.flex = `0 ${w < 10 ? 0 : w}px`; l.style.flex = "1 0"; } } function ontouchend(e) { e.preventDefault(); resizer.removeEventListener("touchmove", ontouchmove); resizer.removeEventListener("touchend", ontouchend); delete e._clientX; } // for desktop function onmousedown(e) { e.preventDefault(); document.addEventListener("mousemove", onmousemove); document.addEventListener("mouseup", onmouseup); } function onmousemove(e) { e.preventDefault(); const clientX = e.clientX; const deltaX = clientX - (resizer._clientX || clientX); resizer._clientX = clientX; const l = resizer.previousElementSibling; const r = resizer.nextElementSibling; // LEFT if (deltaX < 0) { const w = Math.round( parseInt(getComputedStyle(l).width) + deltaX ); l.style.flex = `0 ${w < 10 ? 0 : w}px`; r.style.flex = "1 0"; } // RIGHT if (deltaX > 0) { const w = Math.round( parseInt(getComputedStyle(r).width) - deltaX ); r.style.flex = `0 ${w < 10 ? 0 : w}px`; l.style.flex = "1 0"; } } function onmouseup(e) { e.preventDefault(); document.removeEventListener("mousemove", onmousemove); document.removeEventListener("mouseup", onmouseup); delete e._clientX; } })(); // vertical direction (function resizableY() { const resizer = document.querySelector(".resizer-y"); resizer.addEventListener("mousedown", onmousedown); resizer.addEventListener("touchstart", ontouchstart); // for mobile function ontouchstart(e) { e.preventDefault(); resizer.addEventListener("touchmove", ontouchmove); resizer.addEventListener("touchend", ontouchend); } function ontouchmove(e) { e.preventDefault(); const clientY = e.touches[0].clientY; const deltaY = clientY - (resizer._clientY || clientY); resizer._clientY = clientY; const t = resizer.previousElementSibling; const b = resizer.nextElementSibling; // UP if (deltaY < 0) { const h = Math.round( parseInt(getComputedStyle(t).height) + deltaY ); t.style.flex = `0 ${h < 10 ? 0 : h}px`; b.style.flex = "1 0"; } // DOWN if (deltaY > 0) { const h = Math.round( parseInt(getComputedStyle(b).height) - deltaY ); b.style.flex = `0 ${h < 10 ? 0 : h}px`; t.style.flex = "1 0"; } } function ontouchend(e) { e.preventDefault(); resizer.removeEventListener("touchmove", ontouchmove); resizer.removeEventListener("touchend", ontouchend); delete e._clientY; } // for desktop function onmousedown(e) { e.preventDefault(); document.addEventListener("mousemove", onmousemove); document.addEventListener("mouseup", onmouseup); } function onmousemove(e) { e.preventDefault(); const clientY = e.clientY; const deltaY = clientY - (resizer._clientY || clientY); resizer._clientY = clientY; const t = resizer.previousElementSibling; const b = resizer.nextElementSibling; // UP if (deltaY < 0) { const h = Math.round( parseInt(getComputedStyle(t).height) + deltaY ); t.style.flex = `0 ${h < 10 ? 0 : h}px`; b.style.flex = "1 0"; } // DOWN if (deltaY > 0) { const h = Math.round( parseInt(getComputedStyle(b).height) - deltaY ); b.style.flex = `0 ${h < 10 ? 0 : h}px`; t.style.flex = "1 0"; } } function onmouseup(e) { e.preventDefault(); document.removeEventListener("mousemove", onmousemove); document.removeEventListener("mouseup", onmouseup); delete e._clientY; } })(); })();
HTML
CSS
JS