Lightweight JavaScript Resizable Element Library
Make panels, cards, modals, and layout blocks resizable in plain HTML and JavaScript. hcg-resizable is a zero-dependency library built on the Pointer Events API, so mouse, touch, and pen input share one code path. Eight edge and corner handles, min and max sizing, aspect-ratio locking, and containment are included without jQuery or a framework.
On this page you will find live demos, installation (direct download, npm, CDN), a full options reference, React notes, and copy-paste examples for handles, aspect ratio, containment, and callbacks.
Table of Contents
What is hcg-resizable?
hcg-resizable is a lightweight vanilla JavaScript library for making any element resizable. Call new HcgResizable() on a selector or element, pick which edges and corners get handles, constrain size with min, max, aspect ratio, and containment, and listen to onStart, onResize, and onEnd callbacks - without React, jQuery, or any other dependency.
Why use hcg-resizable?
Most resize solutions are either tied to a framework or ship as part of a large UI toolkit when you only need to stretch a panel or card. jQuery UI Resizable works, but it depends on jQuery and jQuery UI, and touch support needs extra plugins.
hcg-resizable fills that gap: a small, dependency-free library built on Pointer Events for mouse, touch, and pen. It suits vanilla pages, React or Vue dashboards, image crop UIs, and floating panels without pulling in a heavy toolkit. See the comparison table for how it differs from jQuery UI Resizable and hand-rolled scripts, and Features for the full capability list.
Live Demo
Resize the boxes below. Each one shows a different option. For every demo in one place, see the hcg-resizable live demo.
Comparison Table
How hcg-resizable compares with common alternatives.
| Feature | hcg-resizable | jQuery UI resizable | Hand-coded resize |
|---|---|---|---|
| File size | Small (one JS file + CSS) | ~90 KB+ (jQuery + jQuery UI) | Varies |
| Dependencies | None | jQuery + jQuery UI | None |
| Touch and pen support | Yes (Pointer Events) | Needs extra plugin | Manual |
| Edge and corner handles | 8 handles (n, e, s, w, ne, se, sw, nw) | Yes | Manual |
| Pick which handles | Yes (handles array) | Yes | Manual |
| Min and max size | Yes | Yes | Manual |
| Aspect ratio lock | Yes | Yes | Manual |
| Containment | Yes (parent or element) | Yes | Manual |
| North/west anchor adjust | Yes (auto top/left shift) | Yes | Manual |
| Lifecycle callbacks | Yes (onStart, onResize, onEnd) | Yes | Manual |
| Data attributes | Yes (data-hcg-* + HcgResizable.init()) | No | Manual |
Installation
Basic Usage
Create a positioned element, include the CSS and JS files, then pass a selector or DOM element to new HcgResizable().
<div id="panel" style="position:absolute;top:40px;left:40px;width:200px;height:120px;border:solid 1px #aaa">
Drag a handle to resize
</div>
const resize = new HcgResizable('#panel', {
onEnd(event, size) {
console.log('Final size:', size.width, size.height);
}
}); Features
Everything included in the library at a glance:
- Zero dependencies - one JS file and one CSS file.
- Pointer Events - mouse, touch, and pen through one code path.
- Eight handles - north, east, south, west, and all four corners.
- Configurable handles - enable only the edges or corners you need.
- Min and max sizing - clamp width and height during resize.
- Aspect ratio lock - keep proportions with
trueor a numeric ratio. - Containment - stay inside a parent, a CSS selector, or a specific element.
- Window resize clamp -
contain()runs automatically when the window resizes. - North/west anchoring - adjusts
topandleftwhen resizing from north or west edges. - Size persistence - stores last size in
data-hcg-sizeon the element. - Data attributes -
data-hcg-resizableplus option attributes; callHcgResizable.init()when ready. - Runtime options - change any option later with
option()/setOption(). - Multiple elements - one selector can return an array of instances.
- Callbacks -
onStart,onResize, andonEndwith live size data. - Instance API - enable, disable, contain, setSize, getSize, and destroy.
- UMD / ESM / global - works with bundlers, require, or a plain script tag.
- Small footprint - tiny library; works in every modern browser.
Using with React
Create the resizable instance inside a useEffect hook and clean it up with destroy() when the component unmounts.
import { useEffect, useRef } from "react";
import HcgResizable from "hcg-resizable";
import "hcg-resizable/hcg-resizable.css";
function Panel() {
const boxRef = useRef(null);
const resizeRef = useRef(null);
useEffect(() => {
resizeRef.current = new HcgResizable(boxRef.current, {
handles: ['se'],
minWidth: 120,
minHeight: 80,
onEnd: (event, size) => console.log(size.width, size.height)
});
return () => resizeRef.current.destroy();
}, []);
return (
<div ref={boxRef} style={{ position: "absolute", top: 40, left: 40, width: 200, height: 120 }}>
Resize me
</div>
);
} Data Attributes
Every option that takes a simple value can be set in HTML. Mark elements with data-hcg-resizable, then call HcgResizable.init() once the DOM is ready.
| Attribute | Maps to option | Example |
|---|---|---|
| data-hcg-resizable | init target | data-hcg-resizable |
| data-hcg-handles | handles | data-hcg-handles="se" or "n,e,s,w" |
| data-hcg-min-width | minWidth | data-hcg-min-width="80" |
| data-hcg-min-height | minHeight | data-hcg-min-height="60" |
| data-hcg-max-width | maxWidth | data-hcg-max-width="400" |
| data-hcg-max-height | maxHeight | data-hcg-max-height="300" |
| data-hcg-aspect-ratio | aspectRatio | data-hcg-aspect-ratio="true" or "16/9" |
| data-hcg-containment | containment | data-hcg-containment="parent" or "#stage" |
| data-hcg-disabled | disabled | data-hcg-disabled |
| data-hcg-size | restored size | data-hcg-size="200,120" (written on resize end) |
<div
data-hcg-resizable
data-hcg-handles="se"
data-hcg-containment="parent"
data-hcg-aspect-ratio="true">
Resize me
</div> HcgResizable.init(); // every [data-hcg-resizable] element To initialize elements added later, call HcgResizable.init() again, or call the constructor directly on the new element.
Options Reference
Pass these as the second argument to new HcgResizable(element, options).
| Option | Type | Default | Description |
|---|---|---|---|
| handles | String[] | all 8 | Edges and corners to enable: n, e, s, w, ne, se, sw, nw. |
| minWidth | Number | 20 | Minimum width in pixels. |
| minHeight | Number | 20 | Minimum height in pixels. |
| maxWidth | Number | Infinity | Maximum width in pixels. |
| maxHeight | Number | Infinity | Maximum height in pixels. |
| aspectRatio | Boolean or Number | false | true locks the current ratio; a positive number sets width / height. |
| containment | 'parent', String, HTMLElement, or null | null | Clamp size so the element stays inside a container. A string is passed to document.querySelector. |
| disabled | Boolean | false | Start in a disabled state. Call enable() to turn resizing on. |
| onStart | Function or null | null | Fired when a resize begins. Receives (event, size). |
| onResize | Function or null | null | Fired on each pointer move during resize. Receives (event, size). |
| onEnd | Function or null | null | Fired when the resize ends. Receives (event, size). |
size is { width, height } in pixels.
Instance Methods
The constructor returns a resizable instance with the following methods.
| Method | Description |
|---|---|
| option(name) | Gets an option value. |
| option(name, value) | Sets an option value. Returns the instance for chaining. |
| setOption(name, value) | Alias for option(name, value). Rebuilds handles when handles changes; calls contain() when containment or size limits change. |
| contain() | Re-clamps the current size inside the containment area. Runs automatically on window resize when containment is set. |
| enable() | Turns resizing on. Returns the instance for chaining. |
| disable() | Turns resizing off without removing listeners. Returns the instance. |
| setSize(width, height) | Sets the element size in pixels. Updates data-hcg-size. Returns the instance. |
| getSize() | Returns the current size as { width, height }. |
| destroy() | Removes all handles, listeners, and classes. Use this for SPA or framework cleanup. |
Read the library version from the static property:
console.log(HcgResizable.version); Static helpers on the constructor:
HcgResizable.init(); // every [data-hcg-resizable] element
HcgResizable.destroyAll(); // destroy every active instance
var items = HcgResizable('.panel', { handles: ['se'] });
if (Array.isArray(items)) {
items.forEach(function (r) { r.disable(); });
} Callbacks
Pass lifecycle hooks as option functions. Each callback receives the pointer event as the first argument and a size object as the second. Inside the callback, this is the HcgResizable instance.
CSS Classes
hcg-resizable adds a few class names you can target for styling. Handle elements are injected into the resizable element.
| Class | Applied to |
|---|---|
| hcg-resizable | The element the instance is attached to. |
| hcg-resizable-resizing | Present while a resize drag is in progress. |
| hcg-resizable-disabled | Present while resizing is disabled. |
| hcg-resize-handle | Each injected handle element. |
| hcg-resize-handle-{dir} | Direction-specific handle (n, e, s, w, ne, se, sw, nw). |
Browser Support
hcg-resizable works in all modern browsers that support the Pointer Events API.
| Browser | Supported |
|---|---|
| Google Chrome | Yes |
| Mozilla Firefox | Yes |
| Microsoft Edge | Yes |
| Safari | Yes |
| Opera | Yes |
| Mobile browsers | Yes (touch resizing supported) |
License
Released under the MIT License. Free for personal and commercial use. Copyright HTML Code Generator.
Frequently asked questions
Does hcg-resizable have any dependencies?
No. hcg-resizable is plain vanilla JavaScript with zero dependencies. Include hcg-resizable.js and hcg-resizable.css and you are ready to go.
Does hcg-resizable work on touch devices?
Yes. It is built on the Pointer Events API, so mouse, touch, and pen input all work through one code path. Resizable elements set touch-action: none so resizing does not scroll the page accidentally.
Can I lock aspect ratio or keep an element inside a container while resizing?
Yes. Set aspectRatio to true or a number to lock width and height proportionally. Set containment to 'parent' or pass an HTMLElement to clamp size so the element stays inside its container.
Can I use hcg-resizable with React?
Yes. Create the HcgResizable instance inside a useEffect hook, keep a ref to the element, and call destroy() in the cleanup function when the component unmounts. See Using with React on this page.
Can I load hcg-resizable from a CDN?
Yes. Add <link> and <script> tags for hcg-resizable.css and hcg-resizable.js from jsDelivr, unpkg, or your own hosted copy, then call new HcgResizable('.selector'). See Installation and CDN usage on this page.
Related
Related links