Resizable
Panes with a draggable, keyboard-operable divider.
Usage
Handle index is the pane on its leading side — the one whose
share it reports as aria-valuenow and points aria-controls at.
label is required. A separator with a tab stop is
a control, and one that announces only "splitter, 40" gives a keyboard user a number without saying
what it sizes.
Sidebar
Content
The keyboard contract
This is the half every hand-rolled divider skips, and it is the difference between a splitter and a decoration. Tab to the handle above and try it.
- Arrow keys — move the boundary by
step(5% by default). Left/Right in a horizontal group, Up/Down in a vertical one. - Home / End — collapse and expand, as far as the panes' own limits allow.
- Focus ring — the handle is a real tab stop
with
role="separator",aria-orientationand livearia-valuenow.
Two implementation details that only show up in use: the drag uses setPointerCapture, so it survives the pointer leaving a hairline
target — which it does immediately — and the grabbable area is grown to 12px by a
pseudo-element, so the divider can stay 1px wide without being unreasonable to hit.
Vertical
Note that aria-orientation on the handle is the opposite of the group's
direction: it describes the separator's own line, not the direction of travel.
Editor
Console
Limits and clamping
A drag moves one boundary and touches exactly two panes, clamped against both of their limits before anything is applied. Distributing a drag across the whole group is what produces the familiar bug where dragging one divider quietly reflows the far side of the layout.
Clamping only the pane being grown is the other half of that bug: it lets the neighbour shrink
past its own minimum. min defaults to 10 — pass min=0 if a pane should be able to disappear entirely.
Sizes are not persisted. Where that belongs — a
cookie, a user profile, localStorage — is an application decision, and guessing
it wrong is worse than not guessing.
Files
Editor
Inspector
Props
Each part also takes its native element's attributes via prop spreading.
| Prop | Type | Default |
|---|---|---|
direction | Direction | 'horizontal' |
class Extra classes merged onto the group. | string | — |
children required | Snippet | — |
| Prop | Type | Default |
|---|---|---|
min Smallest share of the group this pane accepts, in percent. | number | 10 |
max Largest share, in percent. | number | 90 |
class Extra classes merged onto the pane. | string | — |
children required | Snippet | — |
| Prop | Type | Default |
|---|---|---|
index required Index of the pane on the leading side of this handle — the one whose size `aria-valuenow` reports. | number | — |
label The handle's accessible name, e.g. "Resize sidebar". Required. A `separator` with a tabindex is a control, and a control that announces only "splitter, 40" tells a keyboard user a number without saying what it sizes. | string | — |
step Percent moved per arrow-key press. | number | 5 |
class Extra classes merged onto the handle. | string | — |