range-slider

Multiple native range inputs coordinated on one shared track.

Use ng-range-slider only when two or more native range inputs share one visual track. The parent inspects its direct inputs and computes composite geometry while every input retains native focus, keyboard, form, and AngularTS model behavior. Use the Range element for a single value.

<fieldset>
  <legend>Price range</legend>
  <div ng-range-slider min="0" max="100">
    <input
      aria-label="Minimum price"
      type="range"
      min="0"
      max="100"
      value="25"
    />
    <input
      aria-label="Maximum price"
      type="range"
      min="0"
      max="100"
      value="75"
    />
  </div>
</fieldset>

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 Range Slider</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="minimum = 25; maximum = 75"
    data-example="slider-demo"
  >
    <main class="visual-example">
      <header>
        <label id="price-range-label">Price range</label>
        <output>{{ minimum }}-{{ maximum }}</output>
      </header>
      <div
        ng-range-slider
        min="0"
        max="100"
        aria-labelledby="price-range-label"
      >
        <input
          aria-label="Minimum price"
          type="range"
          min="0"
          max="100"
          ng-model="minimum"
        />
        <input
          aria-label="Maximum price"
          type="range"
          min="0"
          max="100"
          ng-model="maximum"
        />
      </div>
    </main>
  </body>
</html>

Reference workflows

The workflow page covers controlled and multi-thumb ranges, disabled state, right-to-left direction, and vertical orientation. Every thumb uses the same absolute bounds so its native position remains accurate. Applications that require ordered or non-crossing values enforce that policy in AngularTS state.

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Range Slider 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="slider = { controlledStart: 0.3, controlledEnd: 0.7, rangeStart: 25, rangeEnd: 50, multipleOne: 10, multipleTwo: 20, multipleThree: 70, rtl: 75, verticalOne: 50, verticalTwo: 25 }"
    data-example="slider-controlled slider-range slider-multiple slider-rtl slider-vertical"
  >
    <main class="slider-workflow-grid">
      <section
        class="slider-workflow-section"
        aria-labelledby="slider-controlled-title"
      >
        <header>
          <h2 id="slider-controlled-title">Temperature</h2>
          <output>
            {{ slider.controlledStart }}, {{ slider.controlledEnd }}
          </output>
        </header>
        <div ng-range-slider min="0" max="1" aria-label="Temperature range">
          <input
            type="range"
            min="0"
            max="1"
            step="0.1"
            ng-model="slider.controlledStart"
            aria-label="Minimum temperature"
          />
          <input
            type="range"
            min="0"
            max="1"
            step="0.1"
            ng-model="slider.controlledEnd"
            aria-label="Maximum temperature"
          />
        </div>
      </section>

      <section
        class="slider-workflow-section"
        aria-labelledby="slider-range-title"
      >
        <header>
          <h2 id="slider-range-title">Range</h2>
          <output>{{ slider.rangeStart }}–{{ slider.rangeEnd }}</output>
        </header>
        <div ng-range-slider min="0" max="100" aria-label="Price range">
          <input
            type="range"
            min="0"
            max="100"
            step="5"
            ng-model="slider.rangeStart"
            aria-label="Minimum price"
          />
          <input
            type="range"
            min="0"
            max="100"
            step="5"
            ng-model="slider.rangeEnd"
            aria-label="Maximum price"
          />
        </div>
      </section>

      <section
        class="slider-workflow-section"
        aria-labelledby="slider-multiple-title"
      >
        <header>
          <h2 id="slider-multiple-title">Multiple values</h2>
          <output>
            {{ slider.multipleOne }}, {{ slider.multipleTwo }}, {{
            slider.multipleThree }}
          </output>
        </header>
        <div
          ng-range-slider
          min="0"
          max="100"
          aria-label="Multiple slider values"
        >
          <input
            type="range"
            min="0"
            max="100"
            step="10"
            ng-model="slider.multipleOne"
            aria-label="First value"
          />
          <input
            type="range"
            min="0"
            max="100"
            step="10"
            ng-model="slider.multipleTwo"
            aria-label="Second value"
          />
          <input
            type="range"
            min="0"
            max="100"
            step="10"
            ng-model="slider.multipleThree"
            aria-label="Third value"
          />
        </div>
      </section>

      <section
        class="slider-workflow-section"
        dir="rtl"
        lang="ar"
        aria-labelledby="slider-rtl-title"
      >
        <header>
          <h2 id="slider-rtl-title">مستوى الصوت</h2>
          <output>{{ slider.rtl }}</output>
        </header>
        <input
          type="range"
          min="0"
          max="100"
          step="1"
          ng-model="slider.rtl"
          aria-label="مستوى الصوت"
        />
      </section>

      <section
        class="slider-workflow-section slider-workflow-wide"
        aria-labelledby="slider-vertical-title"
      >
        <header>
          <h2 id="slider-vertical-title">Vertical</h2>
          <output> {{ slider.verticalOne }}, {{ slider.verticalTwo }} </output>
        </header>
        <div class="slider-vertical-row">
          <input
            type="range"
            min="0"
            max="100"
            step="1"
            orientation="vertical"
            ng-model="slider.verticalOne"
            aria-label="First vertical value"
          />
          <input
            type="range"
            min="0"
            max="100"
            step="1"
            orientation="vertical"
            ng-model="slider.verticalTwo"
            aria-label="Second vertical value"
          />
        </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-range-slider]. Importing the package registers it with the AngularCSS angular.css module; there is no per-component JavaScript registration step.

Anatomy

Directive selectors

  • ng-range-slider

Semantic structure

Apply ng-range-slider to one container with two or more direct native input[type=range] children sharing the same minimum and maximum. Label every input independently. For one value, use a plain range input without an AngularCSS directive.

API

Attributes and state

AttributeAccessPurpose
aria-orientationOutputInteraction axis exposed to assistive technology.
dirInputText and interaction direction: ltr or rtl.
maxInputMaximum native or component value.
minInputMinimum native or component value.
orientationInput/outputLayout direction: horizontal or vertical.

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
--range-endComponent styling variable.
--range-startComponent styling variable.
--valueComponent 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 coordinates two or more native range inputs on one shared track. It computes only composite geometry and ARIA orientation; each native input and its AngularTS ng-model retain value, focus, keyboard, validation, and form ownership. Use a plain range element when only one value is required.

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

Accessibility

Associate every control with a visible label. Preserve native required, disabled, and invalid semantics, and connect help or error text with aria-describedby.

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-range-slider], 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.