Skip to content

✂ A lightweight, framework-agnostic split-pane library for resizable layouts. Zero dependencies. Modern Pointer Events. CSS-variable driven sizing. ➗

License

Notifications You must be signed in to change notification settings

wutility/split-views

Repository files navigation

SplitViews

A lightweight, framework-agnostic split-pane library for resizable layouts.
Zero dependencies. Modern Pointer Events. CSS-variable driven sizing.

  • Modern: Uses Pointer Events + setPointerCapture (no global listeners)
  • Performant: Batched DOM writes, CSS variables for sizes, minimal reflows
  • 🧩 Composable: Works with nested splits, no framework required
  • Accessible: ARIA roles, orientations, keyboard focusable gutters
split-views split-views split-views split-views

Split views


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 -->

Quick Start

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);
  },
});

Options

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.

API

  • destroy(): Removes gutters and resets styles
  • setSizes(sizes: number[]): Programmatically set pane sizes
  • getSizes(): number[]: Get current pane sizes

Styling

The library sets:

  • display: flex and flex-direction on root
  • flex-basis per pane (via CSS variables)
  • Basic cursor and touch-action on gutters

You 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)

Accessibility

Gutters automatically have:

  • role="separator"
  • aria-orientation="vertical" (for horizontal split) or "horizontal" (for vertical split)
  • tabIndex="0" so they can be focused

Nested Splits

You 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.


Performance Notes

  • Uses setPointerCapture → no global listeners.
  • DOM writes batched with requestAnimationFrame.
  • CSS variables used for sizes → fast style recalculation.
  • Avoid heavy work in onDrag; debounce if needed.
  • Clean destroy() ensures no leaks.

Browser Support

  • Chromium, Firefox, Safari (modern versions with Pointer Events).
  • No IE support (Pointer Events required).

License

MIT © 2025

About

✂ A lightweight, framework-agnostic split-pane library for resizable layouts. Zero dependencies. Modern Pointer Events. CSS-variable driven sizing. ➗

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •