Loading repository data…
Loading repository data…
wutility / repository
✂ A lightweight, framework-agnostic split-pane library for resizable layouts. Zero dependencies. Modern Pointer Events. CSS-variable driven sizing. ➗
A lightweight, framework-agnostic split-pane library for resizable layouts.
Zero dependencies. Modern Pointer Events. CSS-variable driven sizing.
setPointerCapture (no global listeners)
import SplitViews from "split-views";
Or include it via jsDelivr CDN (UMD):
<script src="https://cdn.jsdelivr.net/npm/split-views/dist/index.umd.min.js"></script>
<!-- Access via global object : window.SplitViews -->
HTML:
<div id="editor" class="split-root" style="height: 400px">
<div>Left Pane</div>
<div>Right Pane</div>
</div>
JavaScript:
import SplitViews from "splitviews";
const split = SplitViews({
root: "#editor",
direction: "horizontal", // 'vertical' or 'horizontal' (default)
gutterSize: 8,
sizes: [30, 70], // percentages; defaults to equal split
minSize: [120, 200], // px per pane or single px applied to all
snapOffset: 8, // px tolerance before snapping to min
onDrag: (sizes) => {
console.log("resizing...", sizes);
},
onDragEnd: (sizes) => {
console.log("final sizes:", sizes);
},
});
| Option | Type | Default | Description |
|---|---|---|---|
root | HTMLElement | string | required | Container element or selector. Children become panes. |
direction | 'horizontal' | 'vertical' | 'horizontal' | Split direction. |
gutterSize | number | 10 | Gutter thickness in px. |
gutterClassName | string | 'split-gutter' | Class applied to each gutter. |
minSize | number | number[] | 0 | Per-pane minimum size in px (array) or single px for all. |
sizes | number[] | equal split | Initial sizes in percentages. |
snapOffset | number | 0 | Extra px tolerance before snapping to min. |
onDrag | (sizes:number[])=>void | — | Called on every drag frame. |
onDragEnd | (sizes:number[])=>void | — | Called when dragging stops. |
destroy(): Removes gutters and resets stylessetSizes(sizes: number[]): Programmatically set pane sizesgetSizes(): number[]: Get current pane sizesThe library sets:
display: flex and flex-direction on rootflex-basis per pane (via CSS variables)cursor and touch-action on guttersYou control the look of gutters:
.split-root {
contain: layout size style; /* hint for performance */
}
.split-gutter {
background: transparent;
position: relative;
}
/* Visible hairline */
.split-gutter::before {
content: "";
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.1);
}
.split-gutter:hover::before {
background: rgba(0, 0, 0, 0.2);
}
CSS variables you can use:
--pane-<index>-size: applied as flex-basis for each pane--split-gutter-size: gutter thickness--split-cursor: cursor type (col-resize / row-resize)Gutters automatically have:
role="separator"aria-orientation="vertical" (for horizontal split) or "horizontal" (for
vertical split)tabIndex="0" so they can be focusedYou can nest multiple instances:
const outer = SplitViews({ root: "#root", direction: "horizontal" });
const inner = SplitViews({
root: '#root [data-split-pane="1"]',
direction: "vertical",
});
Each instance manages only its direct children.
setPointerCapture → no global listeners.requestAnimationFrame.onDrag; debounce if needed.destroy() ensures no leaks.MIT © 2025