Resizable
A Tailwind CSS resizable panel component for creating adjustable layouts.
<div class="resizable rounded-lg border h-48 overflow-hidden">
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">One</span>
</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">Two</span>
</div>
</div>Vertical
Use data-direction="vertical" on the container to stack panels vertically.
<div
class="resizable rounded-lg border h-48 overflow-hidden"
data-direction="vertical"
>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">One</span>
</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">Two</span>
</div>
</div>Multiple panels
You can have multiple panels with handles between them.
<div class="resizable rounded-lg border h-48 overflow-hidden">
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 25%"
>
<span class="font-medium">Sidebar</span>
</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">Content</span>
</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 25%"
>
<span class="font-medium">Panel</span>
</div>
</div>Without handle icon
For a minimal look, omit the handle icon element.
<div class="resizable rounded-lg border h-48 overflow-hidden">
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">One</span>
</div>
<div class="resizable-handle" tabindex="0"></div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50"
style="flex-basis: 50%"
>
<span class="font-medium">Two</span>
</div>
</div>Min and max sizes
Use CSS min-width/max-width (or min-height/max-height for vertical layouts) on panels to constrain their size.
Max 16rem
<div class="resizable rounded-lg border h-48 overflow-hidden">
<div
class="resizable-panel flex items-center justify-center bg-muted/50 min-w-24 max-w-64"
style="flex-basis: 30%"
>
<span class="font-medium text-sm text-center">Min 6rem<br />Max 16rem</span>
</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div
class="resizable-panel flex items-center justify-center bg-muted/50 min-w-24"
style="flex-basis: 70%"
>
<span class="font-medium text-sm text-center">Min 6rem</span>
</div>
</div>How it works
The resizable component uses a small JavaScript module that handles drag interactions and keyboard navigation.
Structure
A resizable layout consists of three parts:
.resizable- Container element with optionaldata-direction.resizable-panel- Content panels that can be resized.resizable-handle- Draggable handle between panels
<div class="resizable">
<div class="resizable-panel" style="flex-basis: 50%">Panel 1</div>
<div class="resizable-handle" tabindex="0"></div>
<div class="resizable-panel" style="flex-basis: 50%">Panel 2</div>
</div>Initial sizes
Set the initial size of each panel using inline flex-basis styles with percentage values:
<div class="resizable-panel" style="flex-basis: 30%">Sidebar</div>
<div class="resizable-handle" tabindex="0"></div>
<div class="resizable-panel" style="flex-basis: 70%">Content</div>Size constraints
Use CSS min-width/max-width (or min-height/max-height for vertical) to constrain panel sizes:
<div class="resizable-panel min-w-48 max-w-96">
This panel can be between 12rem and 24rem
</div>Programmatic control
Use the global sp.resizable module to control panels programmatically:
const container = document.querySelector(".resizable");
// Get current sizes (percentages)
const sizes = sp.resizable.getSizes(container);
console.log(sizes); // [30, 70]
// Set sizes (percentages)
sp.resizable.setSizes(container, [40, 60]);Events
The container emits an sp:resize event when panels are resized:
container.addEventListener("sp:resize", (e) => {
console.log(e.detail.sizes); // [40, 60]
});Accessibility
Add tabindex="0" to handles to make them keyboard accessible.
Keyboard navigation
| Key | Action |
|---|---|
ArrowLeft / ArrowUp | Decrease panel size by 1% |
ArrowRight / ArrowDown | Increase panel size by 1% |
Shift + Arrow | Increase/decrease by 10% |
Class reference
All available classes for the resizable component.
| Class | Description |
|---|---|
resizable | Container element for the resizable layout |
resizable-panel | Content panel that can be resized |
resizable-handle | Draggable handle between panels |
resizable-handle-icon | Optional grip icon inside the handle |
<div class="resizable">
<div class="resizable-panel">Content</div>
<div class="resizable-handle" tabindex="0">
<div class="resizable-handle-icon"></div>
</div>
<div class="resizable-panel">Content</div>
</div>Data attributes
All data attributes for the resizable component.
| Attribute | Element | Description |
|---|---|---|
data-direction="vertical" | .resizable | Stack panels vertically instead of horizontally |
<div class="resizable" data-direction="vertical">
<div class="resizable-panel min-h-24">Constrained panel</div>
<div class="resizable-handle" tabindex="0"></div>
<div class="resizable-panel">Panel</div>
</div>