Resizable
Resizable panels with drag handles, visual grips, collapse buttons, and nested layouts.
Basic Horizontal Resizable
Preview
Left Panel
Drag the handle to resize. This panel is 60% by default.
Right Panel
This panel fills the remaining space.
<div class="resizable" style="height: 250px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 60%; padding: 1rem;">
<h4 style="font-weight: 600; margin-bottom: 0.5rem;">Left Panel</h4>
<p style="color: var(--color-base-content); opacity: 0.7;">Drag the handle to resize. This panel is 60% by default.</p>
</div>
<div class="resizable-handle" role="separator" aria-orientation="vertical" tabindex="0"></div>
<div class="resizable-panel" style="padding: 1rem;">
<h4 style="font-weight: 600; margin-bottom: 0.5rem;">Right Panel</h4>
<p style="color: var(--color-base-content); opacity: 0.7;">This panel fills the remaining space.</p>
</div>
</div> Requires: ux.min.css
<div class="flex w-full h-[250px] border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 60%;">
<h4 class="font-semibold mb-2">Left Panel</h4>
</div>
<div class="flex-none w-1 bg-base-300 cursor-col-resize hover:bg-primary transition-colors"></div>
<div class="flex-1 overflow-hidden p-4">
<h4 class="font-semibold mb-2">Right Panel</h4>
</div>
</div> Requires: tw.min.css
// Basic resize handler:
const handle = document.querySelector('.resizable-handle');
const leftPanel = handle.previousElementSibling;
const container = handle.parentElement;
handle.addEventListener('mousedown', (e) => {
document.body.dataset.resizing = 'horizontal';
const startX = e.clientX;
const startWidth = leftPanel.getBoundingClientRect().width;
const onMove = (e) => {
const newWidth = startWidth + (e.clientX - startX);
const pct = (newWidth / container.getBoundingClientRect().width) * 100;
leftPanel.style.flexBasis = Math.min(Math.max(pct, 10), 90) + '%';
};
const onUp = () => {
delete document.body.dataset.resizing;
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}); Vertical Resizable
Preview
Top Panel
Vertical layout — drag the handle up or down.
Bottom Panel
Panels stack vertically.
<div class="resizable resizable-vertical" style="height: 400px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 50%; padding: 1rem;">
<h4 style="font-weight: 600; margin-bottom: 0.5rem;">Top Panel</h4>
<p style="color: var(--color-base-content); opacity: 0.7;">Vertical layout — drag the handle up or down.</p>
</div>
<div class="resizable-handle" role="separator" aria-orientation="horizontal" tabindex="0"></div>
<div class="resizable-panel" style="padding: 1rem;">
<h4 style="font-weight: 600; margin-bottom: 0.5rem;">Bottom Panel</h4>
<p style="color: var(--color-base-content); opacity: 0.7;">Panels stack vertically.</p>
</div>
</div> Requires: ux.min.css
<div class="flex flex-col w-full h-100 border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 50%;">
<h4 class="font-semibold mb-2">Top Panel</h4>
<p class="text-base-content/70">Vertical layout — drag the handle up or down.</p>
</div>
<div class="flex-none h-1 bg-base-300 cursor-row-resize hover:bg-primary transition-colors" role="separator" aria-orientation="horizontal" tabindex="0"></div>
<div class="flex-1 overflow-hidden p-4">
<h4 class="font-semibold mb-2">Bottom Panel</h4>
<p class="text-base-content/70">Panels stack vertically.</p>
</div>
</div> Requires: tw.min.css
// Same pattern as horizontal but track clientY instead of clientX With Grip Handle
Preview
Panel A
Panel B
<div class="resizable" style="height: 250px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 50%; padding: 1rem;">
<p style="font-weight: 600;">Panel A</p>
</div>
<div class="resizable-handle" role="separator" tabindex="0">
<div class="resizable-grip">
<svg viewBox="0 0 6 16" fill="currentColor"><circle cx="1" cy="2" r="1"/><circle cx="5" cy="2" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="5" cy="6" r="1"/><circle cx="1" cy="10" r="1"/><circle cx="5" cy="10" r="1"/><circle cx="1" cy="14" r="1"/><circle cx="5" cy="14" r="1"/></svg>
</div>
</div>
<div class="resizable-panel" style="padding: 1rem;">
<p style="font-weight: 600;">Panel B</p>
</div>
</div> Requires: ux.min.css
<div class="flex w-full h-62.5 border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 50%;">
<p class="font-semibold">Panel A</p>
</div>
<div class="flex-none w-1 bg-base-300 cursor-col-resize hover:bg-primary transition-colors flex items-center justify-center relative" role="separator" tabindex="0">
<div class="flex items-center justify-center z-10 bg-base-100 border border-base-300 rounded" style="width: 12px; height: 1rem;">
<svg class="w-2.5 h-2.5" viewBox="0 0 6 16" fill="currentColor" style="color: color-mix(in oklch, var(--color-base-content) 40%, transparent);"><circle cx="1" cy="2" r="1"/><circle cx="5" cy="2" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="5" cy="6" r="1"/><circle cx="1" cy="10" r="1"/><circle cx="5" cy="10" r="1"/><circle cx="1" cy="14" r="1"/><circle cx="5" cy="14" r="1"/></svg>
</div>
</div>
<div class="flex-1 overflow-hidden p-4">
<p class="font-semibold">Panel B</p>
</div>
</div> Requires: tw.min.css
// No JavaScript required for styling — add resize logic as needed Handle Variants
Preview
Hidden handle (appears on hover)
Right panel
Bordered handle
Right panel
<div class="flex flex-col gap-4">
<!-- Hidden handle -->
<div class="resizable" style="height: 150px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 50%; padding: 1rem;">
<p class="text-sm font-medium">Hidden handle (appears on hover)</p>
</div>
<div class="resizable-handle resizable-handle-hidden" role="separator" tabindex="0"></div>
<div class="resizable-panel" style="padding: 1rem;">
<p class="text-sm">Right panel</p>
</div>
</div>
<!-- Bordered handle -->
<div class="resizable" style="height: 150px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 50%; padding: 1rem;">
<p class="text-sm font-medium">Bordered handle</p>
</div>
<div class="resizable-handle resizable-handle-bordered" role="separator" tabindex="0"></div>
<div class="resizable-panel" style="padding: 1rem;">
<p class="text-sm">Right panel</p>
</div>
</div>
</div> Requires: ux.min.css
<div class="flex flex-col gap-4">
<!-- Hidden handle -->
<div class="flex w-full h-37.5 border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 50%;">
<p class="text-sm font-medium">Hidden handle (appears on hover)</p>
</div>
<div class="flex-none w-1 bg-transparent cursor-col-resize hover:bg-primary transition-colors" role="separator" tabindex="0"></div>
<div class="flex-1 overflow-hidden p-4">
<p class="text-sm">Right panel</p>
</div>
</div>
<!-- Bordered handle -->
<div class="flex w-full h-37.5 border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 50%;">
<p class="text-sm font-medium">Bordered handle</p>
</div>
<div class="flex-none w-1 bg-transparent border-l border-base-300 cursor-col-resize hover:border-primary transition-colors" role="separator" tabindex="0"></div>
<div class="flex-1 overflow-hidden p-4">
<p class="text-sm">Right panel</p>
</div>
</div>
</div> Requires: tw.min.css
// No JavaScript required for styling Three Panels
Preview
Sidebar
Main
Details
<div class="resizable" style="height: 250px; border: 1px solid var(--color-base-300); border-radius: var(--radius-box, 0.75rem); overflow: hidden;">
<div class="resizable-panel" style="flex-basis: 25%; padding: 1rem; background: color-mix(in oklch, var(--color-primary) 5%, transparent);">
<p class="text-sm font-medium">Sidebar</p>
</div>
<div class="resizable-handle" role="separator" tabindex="0"></div>
<div class="resizable-panel" style="flex-basis: 50%; padding: 1rem;">
<p class="text-sm font-medium">Main</p>
</div>
<div class="resizable-handle" role="separator" tabindex="0"></div>
<div class="resizable-panel" style="flex-basis: 25%; padding: 1rem; background: color-mix(in oklch, var(--color-success) 5%, transparent);">
<p class="text-sm font-medium">Details</p>
</div>
</div> Requires: ux.min.css
<div class="flex w-full h-62.5 border border-base-300 rounded-box overflow-hidden">
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 25%; background: color-mix(in oklch, var(--color-primary) 5%, transparent);">
<p class="text-sm font-medium">Sidebar</p>
</div>
<div class="flex-none w-1 bg-base-300 cursor-col-resize hover:bg-primary transition-colors" role="separator" tabindex="0"></div>
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 50%;">
<p class="text-sm font-medium">Main</p>
</div>
<div class="flex-none w-1 bg-base-300 cursor-col-resize hover:bg-primary transition-colors" role="separator" tabindex="0"></div>
<div class="flex-1 overflow-hidden p-4" style="flex-basis: 25%; background: color-mix(in oklch, var(--color-success) 5%, transparent);">
<p class="text-sm font-medium">Details</p>
</div>
</div> Requires: tw.min.css
// Each handle resizes its adjacent panels independently