Skip to content

Resizable Container

A lightweight utility component that adds resize handles around any element and allows the user to resize it by dragging the handles. Works with mouse and touch and supports min/max constraints and fine-grained control over which sides/corners are resizable.

See the Example by Serhii Pimenov on CodePen.

<div data-role="resizable-container"></div>

Restrict sides/corners and set constraints

Section titled “Restrict sides/corners and set constraints”
<div
data-role="resizable-container"
data-resize-pointers="n, s, e, w" <!-- allow edges only -->
data-min-width="150"
data-min-height="120"
data-max-width="600" <!-- 0 means no limit -->
data-max-height="0"
></div>

You can hide the handles and disable interactions via data-enable-resize or API methods:

<div id="box" data-role="resizable-container" data-enable-resize="false"></div>
<script>
// Later
const inst = Metro.getPlugin("#box", "resizable-container")
inst.enable() // shows handles, enables interactions
inst.disable() // hides handles, disables interactions
// Alternatively via attribute (the component reacts to this change):
$("#box").attr("data-enable-resize", "true")
</script>
<div id="my-resizable"></div>
<script>
Metro.makePlugin("#my-resizable", "resizable-container", {
canResize: true,
resizePointers: "nw, ne, se, sw",
minWidth: 150,
minHeight: 100,
})
</script>
ParameterTypeDefaultDescription
canResizebooleantrueEnables or disables the resize interactions (pointer down is ignored when false).
resizePointersstring"nw, n, ne, e, se, s, sw, w"Comma-separated list of allowed handles. Valid values: n, s, e, w, ne, nw, se, sw.
minWidthnumber0Minimum width in pixels.
minHeightnumber0Minimum height in pixels.
maxWidthnumber0Maximum width in pixels; 0 means no maximum.
maxHeightnumber0Maximum height in pixels; 0 means no maximum.
initWidthnumber0Initital width in pixels.
initHeightnumber0Initial height in pixels.

Example (HTML attributes):

<div
data-role="resizable-container"
data-resize-pointers="ne, se, sw, nw"
data-min-width="200"
data-min-height="150"
></div>

Notes:

  • Data attributes use dashed-case names that match option names: e.g. data-resize-pointersresizePointers.
  • Constraints with value 0 are treated as unlimited.
EventDescription
onResizeStartFired when the user starts resizing.
onResizeFired when the user is resizing.
onResizeStopFired when the user stops resizing.
onResizeEnableFired when resize mode enabled.
onResizeDisableFired when resize mode disabole.

Example usage of the create event via data-attribute:

<div
data-role="resizable-container"
data-on-resize="onResize"
></div>
<script>
function onResize(size, element, point) {
// this === el
// size = {top, left, width, height}
// element = the DOM element being resized
// point = one of "n", "s", "e", "w", "ne", "nw", "se", "sw"
}
</script>
  • enable() — Show the handles and enable resize interactions.
  • disable() — Hide the handles and disable resize interactions.
  • destroy() — Remove the element from the DOM.

Example:

const rc = Metro.getPlugin("#my-resizable", "resizable-container")
rc.disable()
rc.enable()
VariableValueDescription
--resizable-container-border-width1pxBorder width of the dotted outline and handles.
--resizable-container-point-size8pxSize (width and height) of each handle.
VariableDefault (Light)Dark ModeDescription
--resizable-container-border-color#000#fffColor of the dotted border and handles outline.

Example:

#my-resizable {
--resizable-container-border-color: var(--color-crimson);
--resizable-container-border-width: 2px;
--resizable-container-point-size: 10px;
}
  • .resizable-container — Root class added to the target element.
  • .rc-contour — Internal overlay that draws the dotted border and contains the handles. When .disabled is present on this element, handles are hidden.
  • .rc-point — Base class for each handle.
  • Modifiers set the position and cursor: .-n, .-s, .-e, .-w, .-ne, .-nw, .-se, .-sw.
  • The component ensures the target element has position: relative if it was static to support top/left updates while resizing.
  • Set an initial width and height on the element (inline style or CSS) so users can see/drag from a sensible starting size.
  • When used with draggable, consider toggle flows (e.g., enable/disable resize via a hotkey) to avoid accidental drags while resizing.
  • Prefer setting minWidth/minHeight to avoid collapsing to very small sizes.
  • Keep resizePointers concise to match your UX: use only the handles your design needs.
  • Avoid modifying the internal .rc-contour structure directly; prefer CSS variables for styling.
  • Always check for updates and compatibility with the latest version of Metro UI.