Resizable

A Tailwind CSS resizable panel component for creating adjustable layouts.

One
Two
<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.

One
Two
<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.

Sidebar
Content
Panel
<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.

One
Two
<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.

Min 6rem
Max 16rem
Min 6rem
<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:

  1. .resizable - Container element with optional data-direction
  2. .resizable-panel - Content panels that can be resized
  3. .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

KeyAction
ArrowLeft / ArrowUpDecrease panel size by 1%
ArrowRight / ArrowDownIncrease panel size by 1%
Shift + ArrowIncrease/decrease by 10%

Class reference

All available classes for the resizable component.

ClassDescription
resizableContainer element for the resizable layout
resizable-panelContent panel that can be resized
resizable-handleDraggable handle between panels
resizable-handle-iconOptional 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.

AttributeElementDescription
data-direction="vertical".resizableStack 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>