resizable

Pointer- and keyboard-resizable split panels powered by --panel-size CSS variables.

Use ng-resizable-panel-group with alternating native section and hr elements. Resize separators support pointer dragging and keyboard control.

<div ng-resizable-panel-group aria-label="Resizable layout">
  <section style="--panel-size: 1">Preview</section>
  <hr aria-label="Resize preview and details" />
  <section>Details</section>
</div>

Set orientation="vertical" on the group to stack panels. Handles receive separator roles, orientation, value bounds, current values, and aria-controls relationships. Dragging or pressing Arrow, Home, and End keys updates adjacent panel --panel-size values within data-min-size and data-max-size; RTL reverses horizontal changes. CSS renders a visible grip without additional markup.

Example

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Resizable</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body ng-app="angular.css" ng-cloak data-example="resizable-demo">
    <div
      ng-resizable-panel-group
      orientation="horizontal"
      aria-label="Resizable layout"
      class="visual-example"
    >
      <section style="--panel-size: 1">
        <div class="resizable-panel-content"><strong>One</strong></div>
      </section>
      <hr aria-label="Resize panel one and panels two and three" />
      <section style="--panel-size: 1">
        <div
          ng-resizable-panel-group
          orientation="vertical"
          aria-label="Resize panels two and three"
        >
          <section style="--panel-size: 1">
            <div class="resizable-panel-content"><strong>Two</strong></div>
          </section>
          <hr aria-label="Resize panel two and panel three" />
          <section style="--panel-size: 3">
            <div class="resizable-panel-content"><strong>Three</strong></div>
          </section>
        </div>
      </section>
    </div>
  </body>
</html>

Orientations and RTL

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Resizable Workflows</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body
    ng-app="angular.css"
    ng-cloak
    data-example="resizable-handle resizable-rtl resizable-vertical"
  >
    <main class="resizable-workflows visual-example">
      <section aria-label="Visible handle example">
        <div
          ng-resizable-panel-group
          id="handle-layout"
          orientation="horizontal"
          aria-label="Sidebar and content layout"
          class="resizable-reference-layout"
        >
          <section style="--panel-size: 1">
            <div class="resizable-panel-content"><strong>Sidebar</strong></div>
          </section>
          <hr aria-label="Resize sidebar and content" />
          <section style="--panel-size: 3">
            <div class="resizable-panel-content"><strong>Content</strong></div>
          </section>
        </div>
      </section>

      <section aria-label="Vertical layout example">
        <div
          ng-resizable-panel-group
          id="vertical-layout"
          orientation="vertical"
          data-step="0.5"
          aria-label="Header and content layout"
          class="resizable-reference-layout"
        >
          <section
            data-min-size="0.5"
            data-max-size="3.5"
            style="--panel-size: 1"
          >
            <div class="resizable-panel-content"><strong>Header</strong></div>
          </section>
          <hr aria-label="Resize header and content" />
          <section data-min-size="0.5" style="--panel-size: 3">
            <div class="resizable-panel-content"><strong>Content</strong></div>
          </section>
        </div>
      </section>

      <section
        class="resizable-workflow-wide"
        aria-label="Right to left nested layout example"
        lang="ar"
      >
        <div
          ng-resizable-panel-group
          id="rtl-layout"
          orientation="horizontal"
          aria-label="تخطيط قابل لتغيير الحجم"
          class="resizable-reference-layout"
          dir="rtl"
        >
          <section style="--panel-size: 1">
            <div class="resizable-panel-content"><strong>واحد</strong></div>
          </section>
          <hr aria-label="تغيير حجم اللوحات" />
          <section style="--panel-size: 1">
            <div
              ng-resizable-panel-group
              orientation="vertical"
              aria-label="تغيير حجم اللوحتين الثانية والثالثة"
              dir="rtl"
            >
              <section style="--panel-size: 1">
                <div class="resizable-panel-content">
                  <strong>اثنان</strong>
                </div>
              </section>
              <hr aria-label="تغيير حجم اللوحتين الثانية والثالثة" />
              <section style="--panel-size: 3">
                <div class="resizable-panel-content">
                  <strong>ثلاثة</strong>
                </div>
              </section>
            </div>
          </section>
        </div>
      </section>
    </main>
  </body>
</html>

Reactive Structure

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Resizable State Workflows</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body
    ng-app="angular.css"
    ng-cloak
    ng-init="resizableState={orientation:'horizontal',firstSize:1,showThird:false}"
  >
    <main class="resizable-state-workflows">
      <section class="resizable-state-section" aria-labelledby="state-title">
        <h2 id="state-title">Reactive layout</h2>
        <div class="resizable-state-actions">
          <button
            size="sm"
            type="button"
            ng-click="resizableState.orientation=resizableState.orientation==='horizontal'?'vertical':'horizontal'"
          >
            Toggle orientation
          </button>
          <button size="sm" type="button" ng-click="resizableState.firstSize=2">
            Set first size to 2
          </button>
          <button
            size="sm"
            type="button"
            ng-click="resizableState.showThird=true"
          >
            Add third panel
          </button>
        </div>
        <div
          ng-resizable-panel-group
          id="state-layout"
          orientation="{{ resizableState.orientation }}"
          data-step="0.25"
          aria-label="Reactive resizable layout"
          class="resizable-reference-layout"
        >
          <section
            id="state-first-panel"
            style="--panel-size: {{ resizableState.firstSize }}"
          >
            <div class="resizable-panel-content"><strong>One</strong></div>
          </section>
          <hr
            id="state-first-handle"
            aria-label="Resize first and second panels"
          />
          <section style="--panel-size: 1">
            <div class="resizable-panel-content"><strong>Two</strong></div>
          </section>
          <hr
            ng-if="resizableState.showThird"
            id="state-inserted-handle"
            aria-label="Resize second and third panels"
          />
          <section
            ng-if="resizableState.showThird"
            id="state-inserted-panel"
            style="--panel-size: 1"
          >
            <div class="resizable-panel-content"><strong>Three</strong></div>
          </section>
        </div>
      </section>

      <section class="resizable-state-section" aria-labelledby="bounds-title">
        <h2 id="bounds-title">Bounded vertical layout</h2>
        <div
          ng-resizable-panel-group
          id="bounded-layout"
          orientation="vertical"
          data-step="0.5"
          aria-label="Bounded vertical layout"
          class="resizable-reference-layout"
        >
          <section
            data-min-size="0.5"
            data-max-size="2"
            style="--panel-size: 1"
          >
            <div class="resizable-panel-content"><strong>Top</strong></div>
          </section>
          <hr aria-label="Resize bounded panels" />
          <section data-min-size="0.5" style="--panel-size: 1">
            <div class="resizable-panel-content"><strong>Bottom</strong></div>
          </section>
        </div>
      </section>
    </main>
  </body>
</html>

Installation

Install AngularCSS, load its stylesheet, and include the angular.css module in your AngularTS application. See Installation for the complete setup.

This component’s root directive is [ng-resizable-panel-group]. Importing the package registers it with the AngularCSS angular.css module; there is no per-component JavaScript registration step.

Anatomy

Directive selectors

  • ng-resizable-panel-group

Semantic structure

Alternate direct .resizable-panel and .resizable-handle children inside each panel group. The root directive inspects those children; no child directives are required. Nested groups belong inside a panel.

API

Attributes and state

AttributeAccessPurpose
aria-controlsOutputID of the element controlled by a trigger.
aria-disabledInputSemantic disabled state.
aria-orientationInput/outputInteraction axis exposed to assistive technology.
aria-valuemaxOutputMaximum value exposed by an adjustable control.
aria-valueminOutputMinimum value exposed by an adjustable control.
aria-valuenowOutputCurrent value exposed by an adjustable control.
data-max-sizeInputLargest panel flex size allowed during resizing.
data-min-sizeInputSmallest panel flex size allowed during resizing.
data-resizingOutputPresent while a pointer resize operation is active.
data-stepInputPanel flex-size increment used by keyboard resizing.
dirInputText and interaction direction: ltr or rtl.
orientationInput/outputResize axis: horizontal or vertical.
tabindexInput/outputKeyboard focus order for composite descendants.

Input attributes are read from authored HTML. Output attributes are maintained by AngularCSS for CSS and testing. Input/output attributes may be authored for a controlled initial state and are then synchronized by the directive.

CSS custom properties

VariablePurpose
--panel-sizeComponent styling variable.

DOM events

This component does not emit a component-specific custom event.

Native DOM events continue to work normally. AngularTS event directives such as ng-click and ng-keydown, plus the data-change model callback, remain application-owned.

Behavior

The directive owns pairwise pointer and keyboard resizing, minimum and maximum bounds, direct-child panel/handle ownership, direction-aware deltas, and synchronized separator state. AngularTS or the application owns authored orientation, initial/external sizes, structural insertion, persistence, and business layout decisions.

AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.

Accessibility

Give each resize handle a concise accessible name. Handles expose separator semantics, the physical resize axis through aria-orientation, current and bounded values, and aria-controls relationships to both adjacent panels. Keyboard resizing follows text direction and preserves visible focus.

Authored accessible names and relationships are preserved. Test the final composition with keyboard navigation and assistive technology because labels and content come from the application.

Customization

Target [ng-resizable-panel-group], semantic descendants, component classes, and generated state with ordinary CSS. Keep behavior and accessible state in the TypeScript directive; visual choices belong in the application stylesheet.

Read Customization for layer order, design tokens, state variants, and iframe demo isolation.