This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Elements

Native HTML elements styled directly, without AngularCSS runtime behavior.

1 - button

Action controls with variant and size styling hooks.

Native button elements and button-type inputs are styled directly. Set variant/size attributes for variants and spacing. A link may opt into the same presentation with a variant attribute when it navigates to another location.

<div class="row">
  <button>Default</button>
  <button variant="outline">Outline</button>
  <button size="sm">Small</button>
</div>

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 Button</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="button-demo">
    <div class="row visual-example">
      <button variant="outline">Button</button>
      <button variant="outline" size="icon" aria-label="Submit">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
          <path
            d="m5 12 7-7 7 7M12 19V5"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
        </svg>
      </button>
    </div>
  </body>
</html>

Variant workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Button 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="button-default button-destructive button-ghost button-icon button-link button-outline button-render button-rounded button-rtl button-secondary button-size button-spinner button-with-icon"
  >
    <main class="workflow-stack">
      <div class="workflow-row" aria-label="Button variants">
        <button>Button</button>
        <button variant="secondary">Secondary</button>
        <button variant="destructive">Destructive</button>
        <button variant="outline">Outline</button>
        <button variant="ghost">Ghost</button>
        <button variant="link">Link</button>
      </div>

      <div class="workflow-row" aria-label="Status buttons">
        <button variant="info">Information</button>
        <button variant="success">Success</button>
        <button variant="warning">Warning</button>
      </div>

      <div class="workflow-row workflow-sizes" aria-label="Button sizes">
        <button size="xs" variant="outline">Extra Small</button>
        <button
          size="icon-xs"
          variant="outline"
          aria-label="Submit extra small"
        >
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path
              d="M7 17 17 7M7 7h10v10"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
        <button size="sm" variant="outline">Small</button>
        <button size="icon-sm" variant="outline" aria-label="Submit small">
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path
              d="M7 17 17 7M7 7h10v10"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
        <button variant="outline">Default</button>
        <button size="icon" variant="outline" aria-label="Submit default">
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path
              d="M7 17 17 7M7 7h10v10"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
        <button size="lg" variant="outline">Large</button>
        <button size="icon-lg" variant="outline" aria-label="Submit large">
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path
              d="M7 17 17 7M7 7h10v10"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
      </div>

      <div class="workflow-row" aria-label="Rounded and icon buttons">
        <a href="#login" variant="secondary" size="sm">Login</a>
        <button type="submit" class="button-rounded">Get Started</button>
        <button
          class="button-rounded"
          variant="outline"
          size="icon"
          aria-label="Continue"
        >
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path
              d="m5 12 7-7 7 7M12 19V5"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
        <button variant="outline">
          <svg
            icon="inline-start"
            viewBox="0 0 24 24"
            fill="none"
            aria-hidden="true"
          >
            <path
              d="M6 3v12M18 9v12M6 9c6 0 6 6 12 6M18 3v3"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
            />
          </svg>
          New Branch
        </button>
        <button variant="outline">
          Fork
          <svg
            icon="inline-end"
            viewBox="0 0 24 24"
            fill="none"
            aria-hidden="true"
          >
            <path
              d="M6 3v12M18 9v12M6 9c6 0 6 6 12 6M18 3v3"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
            />
          </svg>
        </button>
      </div>

      <div class="workflow-row" aria-label="Loading buttons">
        <button variant="outline" disabled>
          <svg
            icon="inline-start"
            aria-hidden="true"
            viewBox="0 0 24 24"
            fill="none"
            class="spinner"
          >
            <path
              d="M21 12a9 9 0 1 1-6.22-8.56"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
            />
          </svg>
          Generating
        </button>
        <button variant="secondary" aria-disabled="true">
          Downloading
          <svg
            icon="inline-end"
            aria-hidden="true"
            viewBox="0 0 24 24"
            fill="none"
            class="spinner"
          >
            <path
              d="M21 12a9 9 0 1 1-6.22-8.56"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
            />
          </svg>
        </button>
      </div>

      <div class="workflow-row" dir="rtl" aria-label="RTL buttons">
        <button variant="outline">زر</button>
        <button variant="destructive">حذف</button>
        <button variant="outline">
          إرسال
          <svg
            icon="inline-end"
            class="rtl-flip"
            viewBox="0 0 24 24"
            fill="none"
            aria-hidden="true"
          >
            <path
              d="m9 18 6-6-6-6"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
      </div>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native button and link activation.

Anatomy

Root styling selector

  • button

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
aria-disabledAuthoredSemantic disabled state.
aria-haspopupAuthoredType of popup controlled by the trigger.
aria-invalidAuthoredValidation state exposed to assistive technology and CSS.
iconAuthoredIcon position: inline-start or inline-end.
sizeAuthoredSize: xs, sm, default, lg, icon-xs, icon-sm, icon, or icon-lg.
variantAuthoredStyle: default, secondary, outline, ghost, link, destructive, info, success, or warning.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native button and link activation. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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

Accessibility

Use a native button whenever the control performs an action. Keep an accessible name, preserve visible focus, and use disabled for unavailable native controls.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

2 - checkbox

Native checkbox control styled from native state.

Use a native checkbox input. AngularCSS styles it directly; native input state and AngularTS ng-model remain the source of truth. Use role="switch" only when the checkbox needs switch semantics and presentation.

<div orientation="horizontal" class="field">
  <input id="terms" name="terms" type="checkbox" ng-model="terms" />
  <label for="terms"> Accept terms </label>
</div>

Set the native HTMLInputElement.indeterminate property from application code when a mixed selection is needed. Native :indeterminate state owns both the visual and accessibility contract; AngularCSS does not create a second checkbox model.

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 Checkbox</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="terms=false;termsDetails=true;wrappedNotifications=false"
    data-example="checkbox-demo"
  >
    <div class="visual-example field-group">
      <div orientation="horizontal" class="field">
        <input
          id="terms-checkbox"
          name="terms-checkbox"
          type="checkbox"
          ng-model="terms"
        />
        <label for="terms-checkbox">Accept terms and conditions</label>
      </div>

      <div orientation="horizontal" class="field">
        <input
          id="terms-checkbox-2"
          name="terms-checkbox-2"
          type="checkbox"
          ng-model="termsDetails"
        />
        <section>
          <label for="terms-checkbox-2">Accept terms and conditions</label>
          <p>By clicking this checkbox, you agree to the terms.</p>
        </section>
      </div>

      <div orientation="horizontal" class="field">
        <input
          id="toggle-checkbox"
          name="toggle-checkbox"
          type="checkbox"
          disabled
        />
        <label for="toggle-checkbox">Enable notifications</label>
      </div>

      <label>
        <div orientation="horizontal" class="field">
          <input
            id="toggle-checkbox-2"
            name="toggle-checkbox-2"
            type="checkbox"
            ng-model="wrappedNotifications"
          />
          <section>
            <strong>Enable notifications</strong>
            <small>
              You can enable or disable notifications at any time.
            </small>
          </section>
        </div>
      </label>

      <output class="visually-hidden" aria-live="polite">
        Terms {{ terms ? 'accepted' : 'not accepted' }}. Detailed terms {{
        termsDetails ? 'accepted' : 'not accepted' }}. Notifications {{
        wrappedNotifications ? 'enabled' : 'disabled' }}.
      </output>
    </div>
  </body>
</html>

States, group, 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 Checkbox 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="basic=false;described=true;hardDisks=true;externalDisks=true;cds=false;servers=false;rtlTerms=false;rtlDetails=true;rtlNotifications=false"
    data-example="checkbox-basic checkbox-description checkbox-disabled checkbox-group checkbox-invalid checkbox-rtl"
  >
    <main class="checkbox-workflow-grid" aria-label="Checkbox workflows">
      <section
        class="checkbox-workflow"
        aria-labelledby="checkbox-basic-heading"
      >
        <h2 id="checkbox-basic-heading">Basic</h2>
        <div class="checkbox-workflow-narrow field-group">
          <div orientation="horizontal" class="field">
            <input
              id="terms-checkbox-basic"
              name="terms-checkbox-basic"
              type="checkbox"
              ng-model="basic"
            />
            <label for="terms-checkbox-basic"
              >Accept terms and conditions</label
            >
          </div>
        </div>
      </section>

      <section
        class="checkbox-workflow"
        aria-labelledby="checkbox-description-heading"
      >
        <h2 id="checkbox-description-heading">Description</h2>
        <div class="checkbox-workflow-description field-group">
          <div orientation="horizontal" class="field">
            <input
              id="terms-checkbox-desc"
              name="terms-checkbox-desc"
              type="checkbox"
              ng-model="described"
            />
            <section>
              <label for="terms-checkbox-desc"
                >Accept terms and conditions</label
              >
              <p>
                By clicking this checkbox, you agree to the terms and
                conditions.
              </p>
            </section>
          </div>
        </div>
      </section>

      <section
        class="checkbox-workflow"
        aria-labelledby="checkbox-disabled-heading"
      >
        <h2 id="checkbox-disabled-heading">Disabled</h2>
        <div class="checkbox-workflow-narrow field-group">
          <div orientation="horizontal" class="field">
            <input
              id="toggle-checkbox-disabled"
              name="toggle-checkbox-disabled"
              type="checkbox"
              disabled
            />
            <label for="toggle-checkbox-disabled">Enable notifications</label>
          </div>
        </div>
      </section>

      <section
        class="checkbox-workflow"
        aria-labelledby="checkbox-invalid-heading"
      >
        <h2 id="checkbox-invalid-heading">Invalid</h2>
        <div class="checkbox-workflow-narrow field-group">
          <div orientation="horizontal" class="field">
            <input
              id="terms-checkbox-invalid"
              name="terms-checkbox-invalid"
              type="checkbox"
              aria-invalid="true"
            />
            <label for="terms-checkbox-invalid"
              >Accept terms and conditions</label
            >
          </div>
        </div>
      </section>

      <section
        class="checkbox-workflow"
        aria-labelledby="checkbox-group-heading"
      >
        <h2 id="checkbox-group-heading">Group</h2>
        <fieldset class="field-set">
          <legend variant="label">Show these items on the desktop:</legend>
          <p>Select the items you want to show on the desktop.</p>
          <div class="checkbox-preference-group field-group">
            <div orientation="horizontal" class="field">
              <input id="hard-disks" type="checkbox" ng-model="hardDisks" />
              <label for="hard-disks">Hard disks</label>
            </div>
            <div orientation="horizontal" class="field">
              <input
                id="external-disks"
                type="checkbox"
                ng-model="externalDisks"
              />
              <label for="external-disks">External disks</label>
            </div>
            <div orientation="horizontal" class="field">
              <input id="cds-dvds" type="checkbox" ng-model="cds" />
              <label for="cds-dvds">CDs, DVDs, and iPods</label>
            </div>
            <div orientation="horizontal" class="field">
              <input
                id="connected-servers"
                type="checkbox"
                ng-model="servers"
              />
              <label for="connected-servers">Connected servers</label>
            </div>
          </div>
        </fieldset>
      </section>

      <section
        class="checkbox-workflow checkbox-workflow-rtl"
        aria-labelledby="checkbox-rtl-heading"
        dir="rtl"
        lang="ar"
      >
        <h2 id="checkbox-rtl-heading">من اليمين إلى اليسار</h2>
        <div class="field-group">
          <div orientation="horizontal" class="field">
            <input
              id="terms-checkbox-rtl"
              type="checkbox"
              ng-model="rtlTerms"
            />
            <label for="terms-checkbox-rtl">قبول الشروط والأحكام</label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="terms-checkbox-2-rtl"
              type="checkbox"
              ng-model="rtlDetails"
            />
            <section>
              <label for="terms-checkbox-2-rtl">قبول الشروط والأحكام</label>
              <p>بالنقر على هذا المربع، فإنك توافق على الشروط.</p>
            </section>
          </div>
          <div orientation="horizontal" class="field">
            <input id="toggle-checkbox-rtl" type="checkbox" disabled />
            <label for="toggle-checkbox-rtl">تفعيل الإشعارات</label>
          </div>
          <label>
            <div orientation="horizontal" class="field">
              <input
                id="toggle-checkbox-2-rtl"
                type="checkbox"
                ng-model="rtlNotifications"
              />
              <section>
                <strong>تفعيل الإشعارات</strong>
                <small>يمكنك تفعيل أو إلغاء تفعيل الإشعارات في أي وقت.</small>
              </section>
            </div>
          </label>
        </div>
      </section>

      <output class="visually-hidden" aria-live="polite">
        Basic {{ basic }}. Described {{ described }}. Hard disks {{ hardDisks
        }}. External disks {{ externalDisks }}. CDs {{ cds }}. Servers {{
        servers }}.
      </output>
    </main>
  </body>
</html>

Table selection

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Checkbox Compositions</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="selection={allRows:false};rows=[{id:'1',name:'Sarah Chen',email:'sarah.chen@example.com',role:'Admin',selected:true},{id:'2',name:'Marcus Rodriguez',email:'marcus.rodriguez@example.com',role:'User',selected:false},{id:'3',name:'Priya Patel',email:'priya.patel@example.com',role:'User',selected:false},{id:'4',name:'David Kim',email:'david.kim@example.com',role:'Editor',selected:false}]"
    data-example="checkbox-table"
  >
    <main class="checkbox-table-demo" aria-label="Checkbox table composition">
      <figure>
        <table aria-label="Team members">
          <thead>
            <tr>
              <th scope="col" class="checkbox-table-select">
                <input
                  id="select-all-checkbox"
                  name="select-all-checkbox"
                  type="checkbox"
                  ng-model="selection.allRows"
                  ng-change="rows[0].selected=selection.allRows;rows[1].selected=selection.allRows;rows[2].selected=selection.allRows;rows[3].selected=selection.allRows"
                  aria-label="Select all rows"
                />
              </th>
              <th scope="col">Name</th>
              <th scope="col">Email</th>
              <th scope="col">Role</th>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="row in rows" aria-selected="{{ row.selected }}">
              <td class="checkbox-table-select">
                <input
                  id="row-{{ row.id }}-checkbox"
                  name="row-{{ row.id }}-checkbox"
                  type="checkbox"
                  ng-model="row.selected"
                  ng-change="selection.allRows=rows[0].selected && rows[1].selected && rows[2].selected && rows[3].selected"
                  aria-label="Select {{ row.name }}"
                />
              </td>
              <td class="checkbox-table-name">{{ row.name }}</td>
              <td>{{ row.email }}</td>
              <td>{{ row.role }}</td>
            </tr>
          </tbody>
        </table>
      </figure>
      <output class="visually-hidden" aria-live="polite">
        Sarah Chen {{ rows[0].selected ? 'selected' : 'not selected' }}. Marcus
        Rodriguez {{ rows[1].selected ? 'selected' : 'not selected' }}. Priya
        Patel {{ rows[2].selected ? 'selected' : 'not selected' }}. David Kim {{
        rows[3].selected ? 'selected' : 'not selected' }}.
      </output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native checkbox state and validation.

Anatomy

Root styling selector

  • input[type="checkbox"]:not([role="switch"])

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
checkedAuthoredInitial native checked state.
disabledAuthoredDisables native or component interaction.
requiredAuthoredMarks a native form value as required.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native checkbox state and validation. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

3 - dialog

Modal dialog structure

Compose a modal from a declarative invoker and native dialog. The browser owns modal focus and disclosure; AngularTS owns form values and application actions.

<section class="dialog">
  <button commandfor="profile-dialog" command="show-modal">Edit profile</button>
  <dialog id="profile-dialog">
    <header>
      <h2>Edit profile</h2>
      <p>Update your public profile.</p>
    </header>
    <button commandfor="profile-dialog" command="close">Save changes</button>
  </dialog>
</section>

Profile Dialog

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 Dialog</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="profile={name:'Pedro Duarte',username:'@peduarte'}; savedName='Pedro Duarte'"
    data-example="dialog-demo"
  >
    <main class="visual-example">
      <section id="profile-dialog" class="dialog">
        <button
          commandfor="profile-dialog-content"
          command="show-modal"
          variant="outline"
        >
          Edit profile
        </button>
        <dialog
          id="profile-dialog-content"
          closedby="any"
          aria-labelledby="profile-dialog-title"
          aria-describedby="profile-dialog-description"
        >
          <header>
            <h2 id="profile-dialog-title">Edit profile</h2>
            <p id="profile-dialog-description">
              Make changes to your profile here. Click save when you're done.
            </p>
          </header>
          <form method="dialog">
            <label for="dialog-name">
              <span>Name</span>
              <input id="dialog-name" ng-model="profile.name" />
            </label>
            <label for="dialog-username">
              <span>Username</span>
              <input id="dialog-username" ng-model="profile.username" />
            </label>
            <footer>
              <button
                type="button"
                commandfor="profile-dialog-content"
                command="close"
                variant="outline"
              >
                Cancel
              </button>
              <button
                type="button"
                commandfor="profile-dialog-content"
                command="close"
                ng-click="savedName=profile.name"
              >
                Save changes
              </button>
            </footer>
          </form>
          <button
            type="button"
            commandfor="profile-dialog-content"
            command="close"
            variant="ghost"
            size="icon-sm"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              aria-hidden="true"
            >
              <path d="M18 6 6 18"></path>
              <path d="m6 6 12 12"></path>
            </svg>
            <span class="visually-hidden">Close</span>
          </button>
        </dialog>
      </section>
      <output class="dialog-output" aria-live="polite">
        Saved profile: <span ng-bind="savedName"></span>
      </output>
    </main>
  </body>
</html>

Close Controls

Corner and footer close actions are distinct, and the corner control can be omitted without changing modal behavior.

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Dialog Close 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="dialog-close-button dialog-no-close-button"
  >
    <main class="dialog-workflow-grid visual-example">
      <section class="dialog-workflow" aria-labelledby="share-heading">
        <h2 id="share-heading">Custom close action</h2>
        <div id="share-dialog" class="dialog">
          <button
            variant="outline"
            type="button"
            commandfor="share-dialog-content"
            command="show-modal"
          >
            Share
          </button>
          <dialog
            id="share-dialog-content"
            closedby="any"
            aria-labelledby="share-dialog-title"
            aria-describedby="share-dialog-description"
          >
            <header>
              <h3 id="share-dialog-title">Share link</h3>
              <p id="share-dialog-description">
                Anyone who has this link will be able to view this project.
              </p>
            </header>
            <div class="dialog-copy-row">
              <input
                aria-label="Share URL"
                value="https://example.com/link/to/document"
                readonly
              />
              <button variant="secondary">Copy Link</button>
            </div>
            <footer>
              <button
                variant="outline"
                commandfor="share-dialog-content"
                command="close"
              >
                Close
              </button>
            </footer>
            <button
              variant="ghost"
              size="icon-sm"
              commandfor="share-dialog-content"
              command="close"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                aria-hidden="true"
              >
                <path d="M18 6 6 18"></path>
                <path d="m6 6 12 12"></path>
              </svg>
              <span class="visually-hidden">Close</span>
            </button>
          </dialog>
        </div>
      </section>

      <section class="dialog-workflow" aria-labelledby="plain-heading">
        <h2 id="plain-heading">Without corner close</h2>
        <div id="plain-dialog" class="dialog">
          <button
            variant="outline"
            type="button"
            commandfor="plain-dialog-content"
            command="show-modal"
          >
            Open dialog
          </button>
          <dialog
            id="plain-dialog-content"
            closedby="any"
            aria-labelledby="plain-dialog-title"
            aria-describedby="plain-dialog-description"
          >
            <header>
              <h3 id="plain-dialog-title">Terms of service</h3>
              <p id="plain-dialog-description">
                Review the current terms before continuing.
              </p>
            </header>
            <p>Your workspace data remains available to members with access.</p>
            <footer>
              <button commandfor="plain-dialog-content" command="close">
                Continue
              </button>
            </footer>
          </dialog>
        </div>
      </section>
    </main>
  </body>
</html>

Scrolling

Use a section directly inside the native dialog or its form for scrollable content, and add class="scroll-area" for native overflow. Keep the footer outside that section when its actions must remain visible.

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Dialog Scroll 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="dialog-scrollable-content dialog-sticky-footer"
  >
    <main class="dialog-workflow-grid visual-example">
      <section class="dialog-workflow" aria-labelledby="scroll-heading">
        <h2 id="scroll-heading">Scrollable content</h2>
        <div id="scroll-dialog" class="dialog">
          <button
            variant="outline"
            type="button"
            commandfor="scroll-dialog-content"
            command="show-modal"
          >
            Read profile
          </button>
          <dialog
            size="wide"
            id="scroll-dialog-content"
            closedby="any"
            aria-labelledby="scroll-dialog-title"
            aria-describedby="scroll-dialog-description"
          >
            <header>
              <h3 id="scroll-dialog-title">About Pedro Duarte</h3>
              <p id="scroll-dialog-description">
                A short professional biography.
              </p>
            </header>
            <section class="dialog-prose">
              <p>
                Pedro is a designer and developer focused on accessible design
                systems and thoughtful product interfaces.
              </p>
              <p>
                He works across interaction design, component architecture, and
                documentation to make complex systems easier to use.
              </p>
              <p>
                His projects explore how strong defaults and composable APIs can
                support teams without limiting their visual language.
              </p>
              <p>
                Outside product work, he studies typography, browser behavior,
                and the details that make keyboard workflows feel dependable.
              </p>
              <p>
                He has collaborated with distributed teams building tools for
                creators, engineers, and operations specialists.
              </p>
              <p>
                This final paragraph ensures the body has genuine overflow and
                remains independently scrollable inside the viewport.
              </p>
            </section>
            <button
              variant="ghost"
              size="icon-sm"
              commandfor="scroll-dialog-content"
              command="close"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                aria-hidden="true"
              >
                <path d="M18 6 6 18"></path>
                <path d="m6 6 12 12"></path>
              </svg>
              <span class="visually-hidden">Close</span>
            </button>
          </dialog>
        </div>
      </section>

      <section class="dialog-workflow" aria-labelledby="sticky-heading">
        <h2 id="sticky-heading">Sticky footer</h2>
        <div id="sticky-dialog" class="dialog">
          <button
            variant="outline"
            type="button"
            commandfor="sticky-dialog-content"
            command="show-modal"
          >
            Review notes
          </button>
          <dialog
            size="wide"
            id="sticky-dialog-content"
            closedby="any"
            aria-labelledby="sticky-dialog-title"
            aria-describedby="sticky-dialog-description"
          >
            <header>
              <h3 id="sticky-dialog-title">Release notes</h3>
              <p id="sticky-dialog-description">
                Review the changes included in this release.
              </p>
            </header>
            <section class="dialog-prose">
              <p>
                Focus is now contained inside modal dialogs while they are open.
              </p>
              <p>
                Background content becomes inert and document scrolling is
                restored when the dialog closes.
              </p>
              <p>
                Internal triggers receive generated relationships to their
                directly owned dialog content.
              </p>
              <p>
                Nested overlays no longer acquire controls belonging to a child
                overlay root.
              </p>
              <p>
                Scrollable bodies retain the header and footer in stable
                positions throughout keyboard and pointer interaction.
              </p>
              <p>
                Logical positioning keeps the corner close control aligned in
                both left-to-right and right-to-left layouts.
              </p>
            </section>
            <footer>
              <button
                variant="outline"
                commandfor="sticky-dialog-content"
                command="close"
              >
                Cancel
              </button>
              <button commandfor="sticky-dialog-content" command="close">
                Confirm
              </button>
            </footer>
          </dialog>
        </div>
      </section>
    </main>
  </body>
</html>

Right To Left

View source
<!doctype html>
<html lang="ar" dir="rtl">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Dialog Rtl</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="profile={name:'محمد علي',username:'@mohamed'}"
    data-example="dialog-rtl"
  >
    <main class="visual-example">
      <section id="rtl-profile-dialog" class="dialog">
        <button
          variant="outline"
          type="button"
          commandfor="rtl-profile-dialog-content"
          command="show-modal"
        >
          تعديل الملف الشخصي
        </button>
        <dialog
          id="rtl-profile-dialog-content"
          closedby="any"
          aria-labelledby="rtl-profile-dialog-title"
          aria-describedby="rtl-profile-dialog-description"
        >
          <header>
            <h2 id="rtl-profile-dialog-title">تعديل الملف الشخصي</h2>
            <p id="rtl-profile-dialog-description">
              غيّر بيانات ملفك الشخصي ثم احفظ التعديلات.
            </p>
          </header>
          <section>
            <label for="rtl-name">
              <span>الاسم</span>
              <input id="rtl-name" ng-model="profile.name" />
            </label>
            <label for="rtl-username">
              <span>اسم المستخدم</span>
              <input id="rtl-username" ng-model="profile.username" />
            </label>
          </section>
          <footer>
            <button
              variant="outline"
              commandfor="rtl-profile-dialog-content"
              command="close"
            >
              إلغاء
            </button>
            <button commandfor="rtl-profile-dialog-content" command="close">
              حفظ التغييرات
            </button>
          </footer>
          <button
            variant="ghost"
            size="icon-sm"
            commandfor="rtl-profile-dialog-content"
            command="close"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              aria-hidden="true"
            >
              <path d="M18 6 6 18"></path>
              <path d="m6 6 12 12"></path>
            </svg>
            <span class="visually-hidden">إغلاق</span>
          </button>
        </dialog>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native dialog top-layer and modal behavior.

Anatomy

Root styling selector

  • .dialog

Semantic structure

Use .dialog as a composition wrapper containing a native invoker button and dialog. Close controls use command=close; semantic headers, sections, forms, and footers need no anatomy classes or nested AngularCSS attributes.

API

Attributes and state

AttributeAccessPurpose
closedbyAuthoredNative dialog dismissal behavior.
commandAuthoredNative invoker action such as show-modal or close.
commandforAuthoredID of the native dialog controlled by an invoker.
dirAuthoredText and interaction direction: ltr or rtl.
sizeAuthoredDialog width: wide; omit for the default width.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

A native dialog opened with command=show-modal owns top-layer rendering, modal focus, Escape, background isolation, and trigger focus restoration. Declarative command=close controls dismiss it. AngularTS remains responsible for form models, validation, submission, authored content, and application state.

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

Accessibility

Use a visible title and description connected with aria-labelledby and aria-describedby. Native modal dialogs contain focus, isolate the background, close on Escape, and restore focus to their declarative invoker.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

4 - input

Native form text entry styled directly by AngularCSS.

Use a native input. AngularCSS styles data-entry input types directly, while the browser and AngularTS own values, events, validation, required state, disabled state, and form behavior.

<input placeholder="Jane Doe" /> <input placeholder="Disabled" disabled />

Use the native size attribute when a compact control should size to its content. The control retains a max-width of 100%; browsers without field-sizing use the requested number of visible characters.

<input value="Compact" size="7" />

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 Input</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="search=''; status=''">
    <div class="stack">
      <label for="docs-input-search">Search</label>
      <input id="docs-input-search" placeholder="Search" ng-model="search" />
      <output class="output"> Value: {{ search ? search : "empty" }} </output>

      <label for="docs-input-compact">Content-sized</label>
      <input id="docs-input-compact" value="Compact" size="7" />

      <label for="docs-input-disabled">Disabled</label>
      <input id="docs-input-disabled" placeholder="Disabled" disabled />

      <label for="docs-input-invalid">Invalid</label>
      <input
        id="docs-input-invalid"
        placeholder="Invalid"
        aria-invalid="true"
      />

      <label for="docs-input-file">File</label>
      <input id="docs-input-file" type="file" />
    </div>
  </body>
</html>

Workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Input 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="inputState={basic:'',apiKey:'',username:'',name:'',email:'',firstName:'',lastName:'',search:'',website:'',required:'',country:'us',formName:'',formEmail:'',phone:'',address:'',message:'Ready'}"
  >
    <main class="input-workflow-grid" aria-label="Input workflows">
      <section data-example="input-basic" class="input-workflow">
        <input
          ng-model="inputState.basic"
          placeholder="Enter text"
          aria-label="Basic input"
        />
      </section>

      <section data-example="input-demo" class="input-workflow">
        <div class="field">
          <label for="input-demo-api-key">API Key</label>
          <input
            id="input-demo-api-key"
            type="password"
            ng-model="inputState.apiKey"
            placeholder="sk-..."
          />
          <p>Your API key is encrypted and stored securely.</p>
        </div>
      </section>

      <section data-example="input-disabled" class="input-workflow">
        <div class="field">
          <label for="input-demo-disabled">Email</label>
          <input
            id="input-demo-disabled"
            type="email"
            placeholder="Email"
            disabled
          />
          <p>This field is currently disabled.</p>
        </div>
      </section>

      <section data-example="input-invalid" class="input-workflow">
        <div class="field">
          <label for="input-invalid-workflow">Invalid Input</label>
          <input
            id="input-invalid-workflow"
            placeholder="Error"
            aria-invalid="true"
          />
          <p>This field contains validation errors.</p>
        </div>
      </section>

      <section data-example="input-required" class="input-workflow">
        <div class="field">
          <label for="input-required-workflow"
            >Required Field <span class="input-required-mark">*</span></label
          >
          <input
            id="input-required-workflow"
            ng-model="inputState.required"
            placeholder="This field is required"
            required
          />
          <p>This field must be filled out.</p>
        </div>
      </section>

      <section data-example="input-file" class="input-workflow">
        <div class="field">
          <label for="input-picture">Picture</label>
          <input id="input-picture" type="file" />
          <p>Select a picture to upload.</p>
        </div>
      </section>

      <section data-example="input-field" class="input-workflow">
        <div class="field">
          <label for="input-field-username">Username</label>
          <input
            id="input-field-username"
            ng-model="inputState.username"
            placeholder="Enter your username"
          />
          <p>Choose a unique username for your account.</p>
        </div>
      </section>

      <section data-example="input-badge" class="input-workflow">
        <div class="field">
          <label for="input-webhook"
            >Webhook URL
            <span variant="secondary" class="input-label-badge badge"
              >Beta</span
            ></label
          >
          <input
            id="input-webhook"
            type="url"
            placeholder="https://api.example.com/webhook"
          />
        </div>
      </section>

      <section
        data-example="input-grid"
        class="input-workflow input-workflow-wide"
      >
        <div class="input-name-grid field-group">
          <div class="field">
            <label for="input-first-name">First Name</label
            ><input
              id="input-first-name"
              ng-model="inputState.firstName"
              placeholder="Jordan"
            />
          </div>
          <div class="field">
            <label for="input-last-name">Last Name</label
            ><input
              id="input-last-name"
              ng-model="inputState.lastName"
              placeholder="Lee"
            />
          </div>
        </div>
      </section>

      <section
        data-example="input-inline"
        class="input-workflow input-workflow-wide"
      >
        <div orientation="horizontal" class="input-inline-demo field">
          <input
            type="search"
            ng-model="inputState.search"
            placeholder="Search..."
            aria-label="Inline search"
          />
          <button
            type="button"
            ng-click="inputState.message='Search '+inputState.search"
          >
            Search
          </button>
        </div>
      </section>

      <section data-example="input-button-group" class="input-workflow">
        <div class="field">
          <label for="input-button-group-workflow">Search</label>
          <div role="group">
            <input
              id="input-button-group-workflow"
              placeholder="Type to search..."
            /><button
              variant="outline"
              type="button"
              ng-click="inputState.message='Button group search'"
            >
              Search
            </button>
          </div>
        </div>
      </section>

      <section data-example="input-input-group" class="input-workflow">
        <div class="field">
          <label for="input-group-url">Website URL</label>
          <div class="input-group">
            <input
              id="input-group-url"
              ng-model="inputState.website"
              placeholder="example.com"
            />
            <div>https://</div>
            <div align="inline-end" aria-label="Website URL information"></div>
          </div>
        </div>
      </section>

      <form
        data-example="input-fieldgroup"
        class="input-workflow input-workflow-form"
        ng-submit="inputState.message='Submitted '+inputState.name"
      >
        <div class="field-group">
          <div class="field">
            <label for="fieldgroup-name">Name</label
            ><input
              id="fieldgroup-name"
              ng-model="inputState.name"
              placeholder="Jordan Lee"
            />
          </div>
          <div class="field">
            <label for="fieldgroup-email">Email</label
            ><input
              id="fieldgroup-email"
              type="email"
              ng-model="inputState.email"
              placeholder="name@example.com"
            />
            <p>We'll send updates to this address.</p>
          </div>
          <div orientation="horizontal" class="input-form-actions field">
            <button
              type="reset"
              variant="outline"
              ng-click="inputState.name='';inputState.email=''"
            >
              Reset</button
            ><button type="submit">Submit</button>
          </div>
        </div>
      </form>

      <form
        data-example="input-form"
        class="input-workflow input-workflow-form input-workflow-form-large"
        ng-submit="inputState.message='Contact submitted '+inputState.formName"
      >
        <div class="field-group">
          <div class="field">
            <label for="form-name">Name</label
            ><input
              id="form-name"
              ng-model="inputState.formName"
              placeholder="Evil Rabbit"
              required
            />
          </div>
          <div class="field">
            <label for="form-email">Email</label
            ><input
              id="form-email"
              type="email"
              ng-model="inputState.formEmail"
              placeholder="john@example.com"
            />
            <p>We'll never share your email with anyone.</p>
          </div>
          <div class="input-name-grid">
            <div class="field">
              <label for="form-phone">Phone</label
              ><input
                id="form-phone"
                type="tel"
                ng-model="inputState.phone"
                placeholder="+1 (555) 123-4567"
              />
            </div>
            <div class="field">
              <label for="form-country">Country</label>
              <select id="form-country" ng-model="inputState.country">
                <option value="us">United States</option>
                <option value="uk">United Kingdom</option>
                <option value="ca">Canada</option>
              </select>
            </div>
          </div>
          <div class="field">
            <label for="form-address">Address</label
            ><input
              id="form-address"
              ng-model="inputState.address"
              placeholder="123 Main St"
            />
          </div>
          <div orientation="horizontal" class="input-form-actions field">
            <button
              type="button"
              variant="outline"
              ng-click="inputState.message='Cancelled'"
            >
              Cancel</button
            ><button type="submit">Submit</button>
          </div>
        </div>
      </form>

      <section
        data-example="input-rtl"
        class="input-workflow"
        dir="rtl"
        lang="ar"
      >
        <div class="field">
          <label for="input-rtl-api-key">مفتاح API</label
          ><input
            id="input-rtl-api-key"
            type="password"
            dir="rtl"
            placeholder="sk-..."
          />
          <p>مفتاح API الخاص بك مشفر ومخزن بأمان.</p>
        </div>
      </section>

      <output class="input-workflow-output"> {{ inputState.message }} </output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native input behavior and AngularTS models.

Anatomy

Root styling selector

  • input:not([type="button"], [type="checkbox"], [type="color"], [type="hidden"], [type="image"], [type="radio"], [type="range"], [type="reset"], [type="submit"])

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
aria-invalidAuthoredValidation state exposed to assistive technology and CSS.
disabledAuthoredDisables native or component interaction.
sizeAuthoredNative number of visible characters; also enables content sizing when supported.
typeAuthoredNative input kind, such as text, email, password, number, search, tel, or url.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Input is a native control styled directly by element and type. AngularTS and the browser own value, events, model synchronization, validation, disabled and required state, and form submission. AngularCSS registers no input directive.

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

Accessibility

Use a native input with a visible label. Preserve native type, name, autocomplete, required, disabled, and validation semantics; use AngularTS ng-model for application state and aria-invalid when application validation must be exposed explicitly.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

5 - kbd

Keyboard shortcut hint

Use native kbd elements. Place related keys next to each other in a span.

<span>
  <kbd>Ctrl</kbd>
  <kbd>K</kbd>
</span>

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 Kbd</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="kbdAction='Ready'"
    data-example="kbd-button kbd-demo kbd-input-group kbd-rtl kbd-tooltip"
  >
    <main class="visual-example">
      <section class="kbd-row">
        <span>Open command menu</span>
        <span><kbd>Ctrl</kbd><kbd>K</kbd></span>
        <span>or</span>
        <kbd aria-label="Slash">/</kbd>
      </section>

      <button variant="outline" type="button" ng-click="kbdAction='Saved'">
        Save changes
        <span><kbd>Ctrl</kbd><kbd>S</kbd></span>
      </button>

      <div class="input-group">
        <input placeholder="Search..." aria-label="Search with shortcut" />
        <div align="inline-end">
          <kbd>⌘K</kbd>
        </div>
      </div>

      <span ng-tooltip>
        <button variant="outline" type="button">Keyboard help</button>
        <span side="top">Press <kbd>?</kbd> to open help.</span>
      </span>

      <section class="kbd-row" dir="rtl" lang="ar">
        <span>فتح قائمة الأوامر</span>
        <span><kbd>Ctrl</kbd><kbd>K</kbd></span>
      </section>

      <output class="kbd-output">{{ kbdAction }}</output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native keyboard-input semantics.

Anatomy

Root styling selector

  • kbd

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

This component has no directive-specific attributes beyond its semantic HTML.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native keyboard-input semantics. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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

Accessibility

Keep the text available to assistive technology and add an accessible label when a visual abbreviation would otherwise be ambiguous.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

6 - label

Label helper that mirrors required/disabled state from its associated control.

Use a native label and connect it with for.

<label for="email">Email</label> <input id="email" required />

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 Label</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="labelTerms=false;labelTermsRtl=false"
    data-example="label-demo label-rtl"
  >
    <main class="visual-example">
      <form class="label-control-contract" aria-label="Label state contract">
        <label for="email">Email</label>
        <input id="email" placeholder="Email" />
        <label for="name">Name</label>
        <input id="name" placeholder="Name" />
      </form>

      <section class="label-checkbox-demo" aria-label="Label checkbox">
        <input id="label-terms" type="checkbox" ng-model="labelTerms" />
        <label for="label-terms">Accept terms and conditions</label>
      </section>

      <section
        class="label-checkbox-demo"
        aria-label="تسمية خانة الاختيار"
        dir="rtl"
        lang="ar"
      >
        <input id="label-terms-rtl" type="checkbox" ng-model="labelTermsRtl" />
        <label for="label-terms-rtl">قبول الشروط والأحكام</label>
      </section>

      <output class="label-output">
        Terms: {{ labelTerms ? 'accepted' : 'not accepted' }} · الشروط: {{
        labelTermsRtl ? 'مقبولة' : 'غير مقبولة' }}
      </output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native form-control association.

Anatomy

Root styling selector

  • label

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
forAuthoredID of the native form control associated with a label.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native form-control association. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

7 - progress

Task completion indicator

Use native progress. Compose its label and value with native label and output elements when needed.

<div>
  <label id="upload-progress-label">Upload progress</label>
  <output>56%</output>
  <progress
    value="56"
    max="100"
    aria-labelledby="upload-progress-label"
  ></progress>
</div>

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 Progress</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>
    <script src="../../js/progress-demo.umd.js"></script>
  </head>
  <body
    ng-app="progressDemo"
    ng-controller="ProgressDemoController"
    ng-cloak
    data-example="progress-demo progress-label"
  >
    <main class="visual-example">
      <section aria-labelledby="progress-timed-title">
        <h2 id="progress-timed-title" class="visually-hidden">
          Loading progress
        </h2>
        <progress
          value="{{ demoValue }}"
          max="100"
          aria-labelledby="progress-timed-title"
          class="progress-demo-timed"
        ></progress>
      </section>

      <section>
        <div class="progress-demo-labeled">
          <label id="upload-progress-label"> Upload progress </label>
          <output for="upload-progress">56%</output>
          <progress
            id="upload-progress"
            value="56"
            max="100"
            aria-labelledby="upload-progress-label"
          ></progress>
        </div>
      </section>
    </main>
  </body>
</html>

Controlled 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 Progress 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="progressWorkflow={controlled:50}"
    data-example="progress-controlled progress-rtl"
  >
    <main class="progress-workflows visual-example">
      <section aria-labelledby="progress-controlled-title">
        <div class="workflow-heading">
          <h2 id="progress-controlled-title">Controlled</h2>
          <output for="progress-controlled-slider">
            {{ progressWorkflow.controlled }}%
          </output>
        </div>
        <progress
          value="{{ progressWorkflow.controlled }}"
          max="100"
          aria-labelledby="progress-controlled-title"
        ></progress>
        <input
          ng-range-slider
          id="progress-controlled-slider"
          type="range"
          min="0"
          max="100"
          step="1"
          ng-model="progressWorkflow.controlled"
          aria-label="Progress value"
        />
      </section>

      <section lang="ar">
        <div dir="rtl">
          <label id="rtl-upload-progress-label"> تقدم الرفع </label>
          <output for="rtl-upload-progress">٥٦%</output>
          <progress
            id="rtl-upload-progress"
            value="56"
            max="100"
            aria-labelledby="rtl-upload-progress-label"
          ></progress>
        </div>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native progress semantics and state.

Anatomy

Root styling selector

  • progress

Semantic structure

Use a native progress element. For a visible label and value, place direct native label, output, and progress children in one div; AngularCSS recognizes that semantic structure without another class.

API

Attributes and state

AttributeAccessPurpose
dirAuthoredText and interaction direction: ltr or rtl.
maxAuthoredMaximum native or component value.
valueAuthoredNative value or authored component value.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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 native progress element owns progressbar semantics and determinate or indeterminate state. Native label and output elements provide optional context. AngularTS may bind value; AngularCSS registers no progress directive.

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

Accessibility

Give every native progress element an accessible name with label, aria-label, or aria-labelledby. Set value and max for determinate progress; omit value for indeterminate progress.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

8 - radio-group

Native radio input grouping with role and focus behavior.

Use a native fieldset with a legend and radio inputs. AngularCSS recognizes the semantic group and styles its native radio descendants directly.

<fieldset>
  <div class="field" orientation="horizontal">
    <input id="default" name="density" type="radio" value="default" />
    <label for="default">Default</label>
  </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 Radio Group</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="density='comfortable'"
    data-example="radio-group-demo"
  >
    <fieldset class="visual-example">
      <legend class="visually-hidden">Density</legend>

      <div orientation="horizontal" class="field">
        <input
          id="density-default"
          name="density"
          type="radio"
          value="default"
          ng-model="density"
        />
        <label for="density-default">Default</label>
      </div>
      <div orientation="horizontal" class="field">
        <input
          id="density-comfortable"
          name="density"
          type="radio"
          value="comfortable"
          ng-model="density"
        />
        <label for="density-comfortable">Comfortable</label>
      </div>
      <div orientation="horizontal" class="field">
        <input
          id="density-compact"
          name="density"
          type="radio"
          value="compact"
          ng-model="density"
        />
        <label for="density-compact">Compact</label>
      </div>

      <output class="visually-hidden" aria-live="polite">
        Selected: <span ng-bind="density"></span>
      </output>
    </fieldset>
  </body>
</html>

Reference Workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Radio Group 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="planType='plus'; densityDescription='comfortable'; disabledChoice='option2'; subscription='monthly'; notification='email'; rtlDensity='comfortable'"
    data-example="radio-group-choice-card radio-group-description radio-group-disabled radio-group-fieldset radio-group-invalid radio-group-rtl"
  >
    <main class="radio-group-workflows">
      <section class="radio-workflow-section" aria-label="Plan choice cards">
        <fieldset class="radio-choice-list">
          <label for="plus-plan" class="radio-choice">
            <div orientation="horizontal" class="field">
              <span>
                <strong>Plus</strong>
                <small> For individuals and small teams. </small>
              </span>
              <input
                id="plus-plan"
                name="plan-type"
                type="radio"
                value="plus"
                ng-model="planType"
              />
            </div>
          </label>
          <label for="pro-plan" class="radio-choice">
            <div orientation="horizontal" class="field">
              <span>
                <strong>Pro</strong>
                <small> For growing businesses. </small>
              </span>
              <input
                id="pro-plan"
                name="plan-type"
                type="radio"
                value="pro"
                ng-model="planType"
              />
            </div>
          </label>
          <label for="enterprise-plan" class="radio-choice">
            <div orientation="horizontal" class="field">
              <span>
                <strong>Enterprise</strong>
                <small> For large teams and enterprises. </small>
              </span>
              <input
                id="enterprise-plan"
                name="plan-type"
                type="radio"
                value="enterprise"
                ng-model="planType"
              />
            </div>
          </label>
        </fieldset>
      </section>

      <section class="radio-workflow-section" aria-label="Density descriptions">
        <fieldset class="radio-description-list">
          <div orientation="horizontal" class="field">
            <input
              id="desc-r1"
              name="density-description"
              type="radio"
              value="default"
              ng-model="densityDescription"
            />
            <section>
              <label for="desc-r1">Default</label>
              <p>Standard spacing for most use cases.</p>
            </section>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="desc-r2"
              name="density-description"
              type="radio"
              value="comfortable"
              ng-model="densityDescription"
            />
            <section>
              <label for="desc-r2">Comfortable</label>
              <p>More space between elements.</p>
            </section>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="desc-r3"
              name="density-description"
              type="radio"
              value="compact"
              ng-model="densityDescription"
            />
            <section>
              <label for="desc-r3">Compact</label>
              <p>Minimal spacing for dense layouts.</p>
            </section>
          </div>
        </fieldset>
      </section>

      <section class="radio-workflow-section" aria-label="Disabled radio">
        <fieldset class="radio-simple-list">
          <div orientation="horizontal" class="field">
            <input
              id="disabled-1"
              name="disabled-choice"
              type="radio"
              value="option1"
              disabled
              ng-model="disabledChoice"
            />
            <label for="disabled-1" class="radio-plain-label"> Disabled </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="disabled-2"
              name="disabled-choice"
              type="radio"
              value="option2"
              ng-model="disabledChoice"
            />
            <label for="disabled-2" class="radio-plain-label"> Option 2 </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="disabled-3"
              name="disabled-choice"
              type="radio"
              value="option3"
              ng-model="disabledChoice"
            />
            <label for="disabled-3" class="radio-plain-label"> Option 3 </label>
          </div>
        </fieldset>
      </section>

      <section
        class="radio-workflow-section"
        aria-label="Subscription fieldset"
      >
        <fieldset class="radio-fieldset field-set">
          <legend variant="label">Subscription Plan</legend>
          <p>Yearly and lifetime plans offer significant savings.</p>

          <div orientation="horizontal" class="field">
            <input
              id="plan-monthly"
              name="subscription"
              type="radio"
              value="monthly"
              ng-model="subscription"
            />
            <label for="plan-monthly" class="radio-plain-label">
              Monthly ($9.99/month)
            </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="plan-yearly"
              name="subscription"
              type="radio"
              value="yearly"
              ng-model="subscription"
            />
            <label for="plan-yearly" class="radio-plain-label">
              Yearly ($99.99/year)
            </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="plan-lifetime"
              name="subscription"
              type="radio"
              value="lifetime"
              ng-model="subscription"
            />
            <label for="plan-lifetime" class="radio-plain-label">
              Lifetime ($299.99)
            </label>
          </div>
        </fieldset>
      </section>

      <section class="radio-workflow-section" aria-label="Invalid radio group">
        <fieldset class="radio-fieldset field-set">
          <legend variant="label">Notification Preferences</legend>
          <p>Choose how you want to receive notifications.</p>

          <div orientation="horizontal" class="field">
            <input
              id="invalid-email"
              name="notification"
              type="radio"
              value="email"
              aria-invalid="true"
              ng-model="notification"
            />
            <label for="invalid-email" class="radio-plain-label">
              Email only
            </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="invalid-sms"
              name="notification"
              type="radio"
              value="sms"
              aria-invalid="true"
              ng-model="notification"
            />
            <label for="invalid-sms" class="radio-plain-label">
              SMS only
            </label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="invalid-both"
              name="notification"
              type="radio"
              value="both"
              aria-invalid="true"
              ng-model="notification"
            />
            <label for="invalid-both" class="radio-plain-label">
              Both Email &amp; SMS
            </label>
          </div>
        </fieldset>
      </section>

      <section
        class="radio-workflow-section"
        aria-label="RTL density options"
        dir="rtl"
        lang="ar"
      >
        <fieldset class="radio-description-list" dir="rtl">
          <div orientation="horizontal" class="field">
            <input
              id="r1-rtl"
              name="rtl-density"
              type="radio"
              value="default"
              dir="rtl"
              ng-model="rtlDensity"
            />
            <section>
              <label for="r1-rtl" dir="rtl">افتراضي</label>
              <p dir="rtl">تباعد قياسي لمعظم حالات الاستخدام.</p>
            </section>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="r2-rtl"
              name="rtl-density"
              type="radio"
              value="comfortable"
              dir="rtl"
              ng-model="rtlDensity"
            />
            <section>
              <label for="r2-rtl" dir="rtl">مريح</label>
              <p dir="rtl">مساحة أكبر بين العناصر.</p>
            </section>
          </div>
          <div orientation="horizontal" class="field">
            <input
              id="r3-rtl"
              name="rtl-density"
              type="radio"
              value="compact"
              dir="rtl"
              ng-model="rtlDensity"
            />
            <section>
              <label for="r3-rtl" dir="rtl">مضغوط</label>
              <p dir="rtl">تباعد أدنى للتخطيطات الكثيفة.</p>
            </section>
          </div>
        </fieldset>
      </section>
    </main>
  </body>
</html>

Field Compositions

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Radio Fields</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="radioFields={subscription:'free',battery:'',security:'',unlock:'',invalid:'',disabled:''}"
    data-example="radio-fields"
  >
    <main class="radio-fields-demo visual-example field-group">
      <fieldset class="field-set">
        <legend variant="label" id="subscription-title">
          Subscription Plan
        </legend>

        <div orientation="horizontal" class="field">
          <input
            id="radio-free"
            name="subscription-plan"
            type="radio"
            value="free"
            ng-model="radioFields.subscription"
          />
          <label for="radio-free" class="radio-plain-label"> Free Plan </label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="radio-pro"
            name="subscription-plan"
            type="radio"
            value="pro"
            ng-model="radioFields.subscription"
          />
          <label for="radio-pro" class="radio-plain-label"> Pro Plan </label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="radio-enterprise"
            name="subscription-plan"
            type="radio"
            value="enterprise"
            ng-model="radioFields.subscription"
          />
          <label for="radio-enterprise" class="radio-plain-label">
            Enterprise
          </label>
        </div>
      </fieldset>

      <fieldset class="field-set" aria-describedby="battery-description">
        <legend variant="label" id="battery-title">Battery Level</legend>
        <p id="battery-description">Choose your preferred battery level.</p>

        <div orientation="horizontal" class="field">
          <input
            id="battery-high"
            name="battery-level"
            type="radio"
            value="high"
            ng-model="radioFields.battery"
          />
          <label for="battery-high">High</label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="battery-medium"
            name="battery-level"
            type="radio"
            value="medium"
            ng-model="radioFields.battery"
          />
          <label for="battery-medium">Medium</label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="battery-low"
            name="battery-level"
            type="radio"
            value="low"
            ng-model="radioFields.battery"
          />
          <label for="battery-low">Low</label>
        </div>
      </fieldset>

      <fieldset class="radio-fields-content-list" aria-label="Device security">
        <div orientation="horizontal" class="field">
          <input
            id="radio-content-1"
            name="device-security"
            type="radio"
            value="touch"
            ng-model="radioFields.security"
          />
          <section>
            <label for="radio-content-1">Enable Touch ID</label>
            <p>Enable Touch ID to quickly unlock your device.</p>
          </section>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="radio-content-2"
            name="device-security"
            type="radio"
            value="biometric"
            ng-model="radioFields.security"
          />
          <section>
            <label for="radio-content-2">
              Enable Touch ID and Face ID to make it even faster to unlock your
              device. This is a long label to test the layout.
            </label>
            <p>Enable Touch ID to quickly unlock your device.</p>
          </section>
        </div>
      </fieldset>

      <fieldset class="radio-fields-title-list" aria-label="Device unlock">
        <label for="radio-title-1">
          <div orientation="horizontal" class="field">
            <input
              id="radio-title-1"
              name="device-unlock"
              type="radio"
              value="touch"
              ng-model="radioFields.unlock"
            />
            <span>
              <strong>Enable Touch ID</strong>
              <small> Enable Touch ID to quickly unlock your device. </small>
            </span>
          </div>
        </label>
        <label for="radio-title-2">
          <div orientation="horizontal" class="field">
            <input
              id="radio-title-2"
              name="device-unlock"
              type="radio"
              value="biometric"
              ng-model="radioFields.unlock"
            />
            <span>
              <strong>
                Enable Touch ID and Face ID to make it even faster to unlock
                your device. This is a long label to test the layout.
              </strong>
              <small> Enable Touch ID to quickly unlock your device. </small>
            </span>
          </div>
        </label>
      </fieldset>

      <fieldset class="field-set">
        <legend variant="label" id="invalid-title">Invalid Radio Group</legend>

        <div orientation="horizontal" class="field">
          <input
            id="radio-invalid-1"
            name="invalid-choice"
            type="radio"
            value="invalid1"
            aria-invalid="true"
            ng-model="radioFields.invalid"
          />
          <label for="radio-invalid-1"> Invalid Option 1 </label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="radio-invalid-2"
            name="invalid-choice"
            type="radio"
            value="invalid2"
            aria-invalid="true"
            ng-model="radioFields.invalid"
          />
          <label for="radio-invalid-2"> Invalid Option 2 </label>
        </div>
      </fieldset>

      <fieldset class="field-set" disabled>
        <legend variant="label" id="disabled-title">
          Disabled Radio Group
        </legend>

        <div orientation="horizontal" class="field">
          <input
            id="radio-disabled-1"
            name="disabled-choice"
            type="radio"
            value="disabled1"
            ng-model="radioFields.disabled"
          />
          <label for="radio-disabled-1"> Disabled Option 1 </label>
        </div>
        <div orientation="horizontal" class="field">
          <input
            id="radio-disabled-2"
            name="disabled-choice"
            type="radio"
            value="disabled2"
            ng-model="radioFields.disabled"
          />
          <label for="radio-disabled-2"> Disabled Option 2 </label>
        </div>
      </fieldset>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native fieldset and radio behavior.

Anatomy

Root styling selector

  • fieldset:has(input[type="radio"]):not(.toggle-group)

Semantic structure

Use a native fieldset with a legend. Place labeled input type="radio" controls inside it and give related controls the same name. AngularCSS styles the fieldset from that semantic structure.

API

Attributes and state

AttributeAccessPurpose
aria-invalidAuthoredValidation state exposed to assistive technology and CSS.
checkedAuthoredInitial native checked state.
dirAuthoredText and interaction direction: ltr or rtl.
disabledAuthoredDisables native or component interaction.
nameAuthoredAuthored HTML attribute or styling hook.
requiredAuthoredMarks a native form value as required.
valueAuthoredNative value or authored component value.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

A native fieldset and legend group radio inputs sharing one name. The browser owns selection, arrow-key behavior, disabled state, validation, and form submission; AngularTS ng-model owns application state. AngularCSS registers no radio-group directive.

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

Accessibility

Use native radio inputs with a shared name and an explicit label for every control. Use fieldset and legend for a visible group label when appropriate. Preserve native disabled and invalid semantics, and connect supporting descriptions 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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

9 - range

A styled native range input with browser-owned interaction and AngularTS model binding.

Use a native range input directly. AngularCSS adds presentation but registers no directive.

<label for="volume">Volume</label>
<input id="volume" type="range" min="0" max="100" ng-model="volume" />
<output for="volume">{{ volume }}</output>

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</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="volume = 75"
    data-example="slider-demo slider-disabled"
  >
    <main class="visual-example">
      <header>
        <label for="volume">Volume</label>
        <output for="volume">{{ volume }}</output>
      </header>
      <input
        id="volume"
        type="range"
        min="0"
        max="100"
        step="1"
        ng-model="volume"
      />

      <header>
        <label for="volume-disabled">Muted</label>
        <output for="volume-disabled">50</output>
      </header>
      <input
        id="volume-disabled"
        type="range"
        min="0"
        max="100"
        step="1"
        value="50"
        disabled
      />
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native range input behavior and styling.

Anatomy

Root styling selector

  • input[type="range"]

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
disabledAuthoredDisables native or component interaction.
maxAuthoredMaximum native or component value.
minAuthoredMinimum native or component value.
orientationAuthoredLayout direction: horizontal or vertical.
stepAuthoredNative numeric step interval.
valueAuthoredNative value or authored component value.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native range input behavior and styling. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

10 - scroll-area

A semantic native overflow region with styled scrollbars.

Apply .scroll-area to a bounded semantic region. Add tabindex="0" when the region should be directly reachable by keyboard.

<section class="scroll-area" tabindex="0" aria-label="Release notes">
  <p>Scrollable content goes here.</p>
</section>

The browser owns keyboard, wheel, touch, pointer, RTL, and scrollbar behavior. AngularTS may add or remove content; native layout updates overflow geometry.

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 Scroll Area</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>
    <section
      class="scroll-demo scroll-area"
      tabindex="0"
      aria-label="Release tags"
    >
      <div class="stack-sm" style="padding: 16px; min-width: 34rem">
        <h3>Tags</h3>
        <span>v1.2.0-beta.50</span>
        <hr />
        <span>v1.2.0-beta.49</span>
        <hr />
        <span>v1.2.0-beta.48</span>
        <hr />
        <span>v1.2.0-beta.47</span>
        <hr />
        <span>v1.2.0-beta.46</span>
        <hr />
        <span>v1.2.0-beta.45</span>
      </div>
    </section>
  </body>
</html>

Workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Scroll Area 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="showOverflow = false; scrollDirection = 'rtl'"
    data-example="scroll-area-demo scroll-area-horizontal-demo scroll-area-rtl"
  >
    <main class="scroll-area-workflows visual-example">
      <section
        class="scroll-area-workflow"
        aria-labelledby="scroll-tags-heading"
      >
        <h2 id="scroll-tags-heading">Tags</h2>
        <section
          class="scroll-area scroll-area-tags"
          id="vertical-scroll-area"
          tabindex="0"
          aria-label="Release tags"
        >
          <div class="scroll-tag-list">
            <span>v1.2.0-beta.50</span>
            <hr />
            <span>v1.2.0-beta.49</span>
            <hr />
            <span>v1.2.0-beta.48</span>
            <hr />
            <span>v1.2.0-beta.47</span>
            <hr />
            <span>v1.2.0-beta.46</span>
            <hr />
            <span>v1.2.0-beta.45</span>
            <hr />
            <span>v1.2.0-beta.44</span>
            <hr />
            <span>v1.2.0-beta.43</span>
            <hr />
            <span>v1.2.0-beta.42</span>
            <hr />
            <span>v1.2.0-beta.41</span>
            <hr />
            <span>v1.2.0-beta.40</span>
            <hr />
            <span>v1.2.0-beta.39</span>
          </div>
        </section>
      </section>

      <section
        class="scroll-area-workflow"
        aria-labelledby="scroll-art-heading"
      >
        <h2 id="scroll-art-heading">Artwork</h2>
        <section
          class="scroll-area scroll-area-artwork"
          id="horizontal-scroll-area"
          tabindex="0"
          aria-label="Featured artists"
        >
          <div class="scroll-artwork-row">
            <figure>
              <img
                src="../../images/avatars/01.png"
                alt="Portrait by Ornella Binni"
              />
              <figcaption>Photo by <strong>Ornella Binni</strong></figcaption>
            </figure>
            <figure>
              <img
                src="../../images/avatars/02.png"
                alt="Portrait by Tom Byrom"
              />
              <figcaption>Photo by <strong>Tom Byrom</strong></figcaption>
            </figure>
            <figure>
              <img
                src="../../images/avatars/03.png"
                alt="Portrait by Vladimir Malyavko"
              />
              <figcaption>
                Photo by <strong>Vladimir Malyavko</strong>
              </figcaption>
            </figure>
            <figure>
              <img
                src="../../images/avatars/04.png"
                alt="Portrait by Sarah Chen"
              />
              <figcaption>Photo by <strong>Sarah Chen</strong></figcaption>
            </figure>
          </div>
        </section>
      </section>

      <section
        class="scroll-area-workflow"
        aria-labelledby="scroll-dynamic-heading"
      >
        <header>
          <h2 id="scroll-dynamic-heading">Dynamic content</h2>
          <button
            type="button"
            variant="outline"
            size="sm"
            ng-click="showOverflow = !showOverflow"
          >
            {{ showOverflow ? 'Remove content' : 'Add content' }}
          </button>
        </header>
        <section
          class="scroll-area scroll-area-dynamic"
          id="dynamic-scroll-area"
          tabindex="0"
          aria-label="Dynamic release notes"
        >
          <div class="scroll-dynamic-content">
            <p>Current release</p>
            <div ng-if="showOverflow" class="scroll-dynamic-overflow">
              <p>Compatibility notes</p>
              <p>Migration details</p>
              <p>API changes</p>
              <p>Resolved issues</p>
            </div>
          </div>
        </section>
      </section>

      <section
        class="scroll-area-workflow"
        aria-labelledby="scroll-rtl-heading"
        dir="rtl"
        lang="ar"
      >
        <header>
          <h2 id="scroll-rtl-heading">العلامات</h2>
          <button
            type="button"
            variant="outline"
            size="sm"
            ng-click="scrollDirection = scrollDirection === 'rtl' ? 'ltr' : 'rtl'"
          >
            Change direction
          </button>
        </header>
        <section
          class="scroll-area scroll-area-tags"
          id="rtl-scroll-area"
          dir="{{ scrollDirection }}"
          tabindex="0"
          aria-label="علامات الإصدار"
        >
          <div class="scroll-tag-list">
            <span>v1.2.0-beta.50</span>
            <hr />
            <span>v1.2.0-beta.49</span>
            <hr />
            <span>v1.2.0-beta.48</span>
            <hr />
            <span>v1.2.0-beta.47</span>
            <hr />
            <span>v1.2.0-beta.46</span>
            <hr />
            <span>v1.2.0-beta.45</span>
            <hr />
            <span>v1.2.0-beta.44</span>
            <hr />
            <span>v1.2.0-beta.43</span>
          </div>
        </section>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native overflow and scrolling.

Anatomy

Root styling selector

  • .scroll-area

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
dirAuthoredText and interaction direction: ltr or rtl.
tabindexAuthoredUse 0 when the overflow region itself must be reachable by keyboard.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

A focusable semantic region with overflow: auto uses the browser’s native scrolling, keyboard behavior, pointer interaction, direction handling, and scrollbar geometry. AngularTS may insert or remove content; native layout updates the overflow automatically. AngularCSS registers no scroll-area directive.

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

Accessibility

Prefer semantic landmarks and native elements inside the layout. Any interactive handles or triggers must retain an accessible name and visible focus indicator.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

11 - select

Native select styling integrated with AngularTS models and form state.

Use a native select directly and bind application state with AngularTS ng-model. No wrapper or styling class is required.

<select id="status" ng-model="status" required>
  <option value="">Select a status</option>
  <option>Todo</option>
  <option>Done</option>
</select>

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 Select</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="status=''">
    <main class="stack-sm visual-example">
      <label for="status">Status</label>
      <select id="status" ng-model="status" required>
        <option value="">Select a status</option>
        <option>Todo</option>
        <option>In progress</option>
        <option>Done</option>
      </select>
      <output class="output">Current: {{ status || 'none' }}</output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native select, option, and optgroup behavior.

Anatomy

Root styling selector

  • select

Semantic structure

Use a native select directly. Native option and optgroup elements need no additional attributes. Use AngularTS ng-model, validators, and form directives directly on the select.

API

Attributes and state

AttributeAccessPurpose
aria-invalidAuthoredValidation state exposed to assistive technology and CSS.
dirAuthoredText and interaction direction: ltr or rtl.
disabledAuthoredDisables native or component interaction.
multipleAuthoredAllows more than one item to remain selected or open.
nameAuthoredAuthored HTML attribute or styling hook.
requiredAuthoredMarks a native form value as required.
sizeAuthoredVisual size token supported by the component stylesheet.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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 native select owns values, option groups, keyboard interaction, disabled state, validation, and form submission. AngularTS supplies option registration, ng-model, validators, and form-state classes. AngularCSS registers no select directive.

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

Accessibility

Use a visible label connected by for and id, or provide another accessible name. Preserve native option, optgroup, multiple, disabled, required, invalid, and direction semantics; AngularTS reflects model and validation state without replacing them.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

12 - separator

Visual and semantic content separator

Use a native hr for a horizontal separator. Add aria-orientation="vertical" only when it is presented as a vertical divider.

<hr />
<hr aria-orientation="vertical" />

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 Separator</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="separator-demo">
    <main class="visual-example">
      <section data-example="separator-demo" class="separator-copy-demo">
        <div>
          <strong>AngularCSS</strong>
          <p class="muted">HTML-first styles for enterprise applications</p>
        </div>
        <hr />
        <p>
          A set of beautifully designed components that you can customize,
          extend, and build on.
        </p>
      </section>

      <section data-example="separator-list" class="separator-list-demo">
        <dl>
          <dt>Item 1</dt>
          <dd>Value 1</dd>
        </dl>
        <hr />
        <dl>
          <dt>Item 2</dt>
          <dd>Value 2</dd>
        </dl>
        <hr />
        <dl>
          <dt>Item 3</dt>
          <dd>Value 3</dd>
        </dl>
      </section>

      <section data-example="separator-menu" class="separator-menu-demo">
        <div><strong>Settings</strong><span>Manage preferences</span></div>
        <hr aria-orientation="vertical" />
        <div><strong>Account</strong><span>Profile &amp; security</span></div>
        <hr aria-orientation="vertical" />
        <div><strong>Help</strong><span>Support &amp; docs</span></div>
      </section>

      <nav
        data-example="separator-vertical"
        class="separator-nav-demo"
        aria-label="Resource links"
      >
        <a href="#blog">Blog</a>
        <hr aria-orientation="vertical" />
        <a href="#docs">Docs</a>
        <hr aria-orientation="vertical" />
        <a href="#source">Source</a>
      </nav>

      <section
        data-example="separator-rtl"
        class="separator-copy-demo"
        dir="rtl"
        lang="ar"
      >
        <div>
          <strong>AngularCSS</strong>
          <p class="muted">الأساس لنظام التصميم الخاص بك</p>
        </div>
        <hr />
        <p>
          مجموعة من المكونات المصممة بشكل جميل يمكنك تخصيصها وتوسيعها والبناء
          عليها.
        </p>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native horizontal-rule semantics.

Anatomy

Root styling selector

  • hr

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
aria-orientationAuthoredSeparator axis: vertical; omit for the native horizontal separator.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native horizontal-rule semantics. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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

Accessibility

Prefer semantic landmarks and native elements inside the layout. Any interactive handles or triggers must retain an accessible name and visible focus indicator.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

13 - switch

Toggleable control with semantic switch state attributes.

Use role="switch" on a native checkbox. The browser and AngularTS own its checked state, validation, and form behavior.

<div orientation="horizontal" class="field">
  <input id="airplane-mode" type="checkbox" role="switch" />
  <label for="airplane-mode">Airplane mode</label>
</div>

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 Switch</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="mode=false"
    data-example="switch-demo"
  >
    <div class="visual-example">
      <input role="switch" id="airplane-mode" type="checkbox" ng-model="mode" />
      <label for="airplane-mode">Airplane Mode</label>
      <output class="visually-hidden" aria-live="polite">
        Mode enabled: <span ng-bind="mode"></span>
      </output>
    </div>
  </body>
</html>

Reference Workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Switch 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="small=false; standard=false; share=false; notifications=true; focus=false; terms=false"
    data-example="switch-choice-card switch-description switch-disabled switch-invalid switch-rtl switch-sizes"
  >
    <main class="switch-workflows">
      <section class="switch-workflow-section" aria-label="Switch sizes">
        <div class="switch-size-list field-group">
          <div orientation="horizontal" class="field">
            <input
              role="switch"
              id="switch-size-sm"
              type="checkbox"
              size="sm"
              ng-model="small"
            />
            <label for="switch-size-sm">Small</label>
          </div>
          <div orientation="horizontal" class="field">
            <input
              role="switch"
              id="switch-size-default"
              type="checkbox"
              size="default"
              ng-model="standard"
            />
            <label for="switch-size-default">Default</label>
          </div>
        </div>
      </section>

      <section class="switch-workflow-section" aria-label="Disabled switch">
        <div orientation="horizontal" class="field">
          <input
            role="switch"
            id="switch-disabled-unchecked"
            type="checkbox"
            disabled
          />
          <label for="switch-disabled-unchecked">Disabled</label>
        </div>
      </section>

      <section class="switch-workflow-section" aria-label="Switch description">
        <div orientation="horizontal" class="field">
          <section>
            <label for="switch-focus-mode">Share across devices</label>
            <p>
              Focus is shared across devices, and turns off when you leave the
              app.
            </p>
          </section>
          <input
            role="switch"
            id="switch-focus-mode"
            type="checkbox"
            ng-model="focus"
          />
        </div>
      </section>

      <section class="switch-workflow-section" aria-label="Invalid switch">
        <div orientation="horizontal" class="field">
          <section>
            <label for="switch-terms"> Accept terms and conditions </label>
            <p>You must accept the terms and conditions to continue.</p>
          </section>
          <input
            role="switch"
            id="switch-terms"
            type="checkbox"
            aria-invalid="true"
            ng-model="terms"
          />
        </div>
      </section>

      <section
        class="switch-workflow-section switch-workflow-wide"
        aria-label="Switch choice cards"
      >
        <div class="switch-choice-list field-group">
          <label for="switch-share" class="switch-choice">
            <div orientation="horizontal" class="field">
              <span>
                <strong>Share across devices</strong>
                <small>
                  Focus is shared across devices, and turns off when you leave
                  the app.
                </small>
              </span>
              <input
                role="switch"
                id="switch-share"
                type="checkbox"
                ng-model="share"
              />
            </div>
          </label>
          <label for="switch-notifications" class="switch-choice">
            <div orientation="horizontal" class="field">
              <span>
                <strong>Enable notifications</strong>
                <small>
                  Receive notifications when focus mode is enabled or disabled.
                </small>
              </span>
              <input
                role="switch"
                id="switch-notifications"
                type="checkbox"
                ng-model="notifications"
              />
            </div>
          </label>
        </div>
      </section>

      <section
        class="switch-workflow-section switch-workflow-wide"
        aria-label="RTL switch"
        dir="rtl"
        lang="ar"
      >
        <div orientation="horizontal" class="field">
          <section>
            <label for="switch-focus-mode-rtl"> المشاركة عبر الأجهزة </label>
            <p>
              يتم مشاركة التركيز عبر الأجهزة، ويتم إيقاف تشغيله عند مغادرة
              التطبيق.
            </p>
          </section>
          <input
            role="switch"
            id="switch-focus-mode-rtl"
            type="checkbox"
            dir="rtl"
          />
        </div>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native checkbox state with switch presentation.

Anatomy

Root styling selector

  • input[type="checkbox"][role="switch"]

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
checkedAuthoredInitial native checked state.
disabledAuthoredDisables native or component interaction.
requiredAuthoredMarks a native form value as required.
roleAuthoredExplicit semantic role when native HTML does not provide one.
sizeAuthoredSwitch size: sm; omit for the default size.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native checkbox state with switch presentation. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

14 - table

Semantic data table

Use a native table inside a figure. AngularCSS styles its semantic table structure directly.

<figure>
  <table>
    <thead>
      <tr>
        <th scope="col">Invoice</th>
      </tr>
    </thead>
  </table>
</figure>

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 Table</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>
    <figure>
      <table>
        <caption>
          A list of recent invoices.
        </caption>
        <thead>
          <tr>
            <th scope="col">Invoice</th>
            <th scope="col">Status</th>
            <th scope="col">Method</th>
            <th class="text-right" scope="col">Amount</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">INV001</th>
            <td>Paid</td>
            <td>Card</td>
            <td class="text-right">$250.00</td>
          </tr>
          <tr>
            <th scope="row">INV002</th>
            <td>Pending</td>
            <td>PayPal</td>
            <td class="text-right">$150.00</td>
          </tr>
          <tr>
            <th scope="row">INV003</th>
            <td>Unpaid</td>
            <td>Transfer</td>
            <td class="text-right">$350.00</td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <td colspan="3">Total</td>
            <td class="text-right">$750.00</td>
          </tr>
        </tfoot>
      </table>
    </figure>
  </body>
</html>

Workflows

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Table 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="invoices=[{id:'INV001',status:'Paid',method:'Credit Card',amount:'$250.00'},{id:'INV002',status:'Pending',method:'PayPal',amount:'$150.00'},{id:'INV003',status:'Unpaid',method:'Bank Transfer',amount:'$350.00'},{id:'INV004',status:'Paid',method:'Credit Card',amount:'$450.00'},{id:'INV005',status:'Paid',method:'PayPal',amount:'$550.00'},{id:'INV006',status:'Pending',method:'Bank Transfer',amount:'$200.00'},{id:'INV007',status:'Unpaid',method:'Credit Card',amount:'$300.00'}];products=[{name:'Wireless Mouse',price:'$29.99'},{name:'Mechanical Keyboard',price:'$129.99'},{name:'USB-C Hub',price:'$49.99'}];payments=[{id:'m5gr84i9',amount:'$316.00',status:'success',statusAr:'ناجح',email:'ken99@example.com',selected:false},{id:'3u1reuv4',amount:'$242.00',status:'success',statusAr:'ناجح',email:'Abe45@example.com',selected:false},{id:'derv1ws0',amount:'$837.00',status:'processing',statusAr:'قيد المعالجة',email:'Monserrat44@example.com',selected:false},{id:'5kma53ae',amount:'$874.00',status:'success',statusAr:'ناجح',email:'Silas22@example.com',selected:false},{id:'bhqecj4p',amount:'$721.00',status:'failed',statusAr:'فشل',email:'carmella@example.com',selected:false}];dataState={query:'',order:'email',all:false,selected:0,showStatus:true,showEmail:true,showAmount:true};rtlDataState={query:'',order:'email',all:false,showStatus:true,showEmail:true,showAmount:true};tableState={action:'Ready'}"
  >
    <main class="table-workflow-grid" aria-label="Table workflows">
      <section
        class="table-workflow table-workflow-wide"
        data-example="table-demo table-footer"
        aria-label="Recent invoices"
      >
        <figure>
          <table>
            <caption>
              A list of your recent invoices.
            </caption>
            <thead>
              <tr>
                <th scope="col">Invoice</th>
                <th scope="col">Status</th>
                <th scope="col">Method</th>
                <th scope="col" class="text-right">Amount</th>
              </tr>
            </thead>
            <tbody>
              <tr ng-repeat="invoice in invoices" animate>
                <th scope="row">{{ invoice.id }}</th>
                <td>{{ invoice.status }}</td>
                <td>{{ invoice.method }}</td>
                <td class="text-right">{{ invoice.amount }}</td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="3">Total</td>
                <td class="text-right">$2,500.00</td>
              </tr>
            </tfoot>
          </table>
        </figure>
      </section>

      <section
        class="table-workflow table-actions-example"
        data-example="table-actions"
        aria-label="Product actions"
      >
        <figure>
          <table>
            <thead>
              <tr>
                <th scope="col">Product</th>
                <th scope="col">Price</th>
                <th scope="col" class="text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr ng-repeat="product in products" animate>
                <th scope="row">{{ product.name }}</th>
                <td>{{ product.price }}</td>
                <td class="text-right">
                  <div ng-dropdown-menu class="table-action-menu">
                    <button
                      variant="ghost"
                      size="icon-xs"
                      type="button"
                      aria-label="Open menu for {{ product.name }}"
                    >
                      <svg viewBox="0 0 24 24" aria-hidden="true">
                        <circle cx="5" cy="12" r="1"></circle>
                        <circle cx="12" cy="12" r="1"></circle>
                        <circle cx="19" cy="12" r="1"></circle>
                      </svg>
                    </button>
                    <menu>
                      <button ng-click="tableState.action='Edit '+product.name">
                        Edit
                      </button>
                      <button
                        ng-click="tableState.action='Duplicate '+product.name"
                      >
                        Duplicate
                      </button>
                      <hr />
                      <button
                        variant="destructive"
                        ng-click="tableState.action='Delete '+product.name"
                      >
                        Delete
                      </button>
                    </menu>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </figure>
      </section>

      <section
        class="table-workflow"
        data-example="table-rtl"
        aria-label="جدول الفواتير"
        dir="rtl"
        lang="ar"
      >
        <figure>
          <table>
            <caption>
              قائمة بفواتيرك الأخيرة.
            </caption>
            <thead>
              <tr>
                <th scope="col">الفاتورة</th>
                <th scope="col">الحالة</th>
                <th scope="col">الطريقة</th>
                <th scope="col" class="text-start">المبلغ</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <th scope="row">INV001</th>
                <td>مدفوع</td>
                <td>بطاقة ائتمانية</td>
                <td>$250.00</td>
              </tr>
              <tr>
                <th scope="row">INV002</th>
                <td>قيد الانتظار</td>
                <td>PayPal</td>
                <td>$150.00</td>
              </tr>
              <tr>
                <th scope="row">INV003</th>
                <td>غير مدفوع</td>
                <td>تحويل بنكي</td>
                <td>$350.00</td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="3">المجموع</td>
                <td>$2,500.00</td>
              </tr>
            </tfoot>
          </table>
        </figure>
      </section>

      <section
        class="table-workflow table-workflow-wide"
        data-example="data-table-demo"
        aria-label="Payments data table"
      >
        <div class="data-table-toolbar">
          <input
            ng-model="dataState.query"
            placeholder="Filter emails..."
            aria-label="Filter payment emails"
          />
          <div ng-dropdown-menu>
            <button variant="outline" type="button">
              Columns <span aria-hidden="true"></span>
            </button>
            <menu>
              <button
                aria-checked="{{ dataState.showStatus }}"
                ng-click="dataState.showStatus=!dataState.showStatus"
              >
                Status
              </button>
              <button
                aria-checked="{{ dataState.showEmail }}"
                ng-click="dataState.showEmail=!dataState.showEmail"
              >
                Email
              </button>
              <button
                aria-checked="{{ dataState.showAmount }}"
                ng-click="dataState.showAmount=!dataState.showAmount"
              >
                Amount
              </button>
            </menu>
          </div>
        </div>
        <figure class="data-table-frame">
          <table>
            <thead>
              <tr>
                <th scope="col" class="data-table-select">
                  <input
                    type="checkbox"
                    ng-model="dataState.all"
                    ng-change="payments[0].selected=dataState.all;payments[1].selected=dataState.all;payments[2].selected=dataState.all;payments[3].selected=dataState.all;payments[4].selected=dataState.all"
                    aria-label="Select all payments"
                  />
                </th>
                <th scope="col" ng-if="dataState.showStatus">Status</th>
                <th scope="col" ng-if="dataState.showEmail">
                  <button
                    variant="ghost"
                    type="button"
                    ng-click="dataState.order=dataState.order==='email' ? '-email' : 'email'"
                  >
                    Email <span aria-hidden="true"></span>
                  </button>
                </th>
                <th scope="col" ng-if="dataState.showAmount" class="text-right">
                  Amount
                </th>
                <th scope="col">
                  <span class="visually-hidden">Actions</span>
                </th>
              </tr>
            </thead>
            <tbody>
              <tr
                ng-repeat="payment in payments | filter:dataState.query | orderBy:dataState.order"
                animate
                aria-selected="{{ payment.selected }}"
              >
                <td class="data-table-select">
                  <input
                    type="checkbox"
                    ng-model="payment.selected"
                    ng-change="dataState.selected=payment.selected ? 1 : 0"
                    aria-label="Select {{ payment.email }}"
                  />
                </td>
                <td ng-if="dataState.showStatus" class="capitalize">
                  {{ payment.status }}
                </td>
                <td ng-if="dataState.showEmail" class="lowercase">
                  {{ payment.email }}
                </td>
                <td
                  ng-if="dataState.showAmount"
                  class="text-right table-cell-medium"
                >
                  {{ payment.amount }}
                </td>
                <td class="text-right">
                  <button
                    variant="ghost"
                    size="icon-xs"
                    type="button"
                    ng-click="tableState.action='Open '+payment.id"
                    aria-label="Open menu for {{ payment.email }}"
                  >
                    •••
                  </button>
                </td>
              </tr>
              <tr ng-if="!(payments | filter:dataState.query).length" animate>
                <td colspan="5" class="data-table-empty">No results.</td>
              </tr>
            </tbody>
          </table>
        </figure>
        <div class="data-table-footer">
          <p>{{ dataState.selected }} of 5 row(s) selected.</p>
          <div class="row">
            <button variant="outline" size="sm" type="button" disabled>
              Previous</button
            ><button variant="outline" size="sm" type="button" disabled>
              Next
            </button>
          </div>
        </div>
      </section>

      <section
        class="table-workflow table-workflow-wide"
        data-example="data-table-rtl"
        aria-label="جدول بيانات المدفوعات"
        dir="rtl"
        lang="ar"
        ng-init="rtlPayments=[{amount:'$316.00',statusAr:'ناجح',email:'ken99@example.com',selected:false},{amount:'$242.00',statusAr:'ناجح',email:'Abe45@example.com',selected:false},{amount:'$837.00',statusAr:'قيد المعالجة',email:'Monserrat44@example.com',selected:false},{amount:'$874.00',statusAr:'ناجح',email:'Silas22@example.com',selected:false},{amount:'$721.00',statusAr:'فشل',email:'carmella@example.com',selected:false}]"
      >
        <div class="data-table-toolbar">
          <input
            ng-model="rtlDataState.query"
            placeholder="تصفية البريد الإلكتروني..."
            aria-label="تصفية البريد الإلكتروني"
          />
          <div ng-dropdown-menu>
            <button variant="outline" type="button">
              الأعمدة <span aria-hidden="true"></span>
            </button>
            <menu>
              <button
                aria-checked="{{ rtlDataState.showStatus }}"
                ng-click="rtlDataState.showStatus=!rtlDataState.showStatus"
              >
                الحالة
              </button>
              <button
                aria-checked="{{ rtlDataState.showEmail }}"
                ng-click="rtlDataState.showEmail=!rtlDataState.showEmail"
              >
                البريد الإلكتروني
              </button>
              <button
                aria-checked="{{ rtlDataState.showAmount }}"
                ng-click="rtlDataState.showAmount=!rtlDataState.showAmount"
              >
                المبلغ
              </button>
            </menu>
          </div>
        </div>
        <figure class="data-table-frame">
          <table>
            <thead>
              <tr>
                <th scope="col" class="data-table-select">
                  <input
                    type="checkbox"
                    ng-model="rtlDataState.all"
                    aria-label="تحديد الكل"
                  />
                </th>
                <th scope="col" ng-if="rtlDataState.showStatus">الحالة</th>
                <th scope="col" ng-if="rtlDataState.showEmail">
                  <button
                    variant="ghost"
                    type="button"
                    ng-click="rtlDataState.order=rtlDataState.order==='email' ? '-email' : 'email'"
                  >
                    البريد الإلكتروني <span aria-hidden="true"></span>
                  </button>
                </th>
                <th scope="col" ng-if="rtlDataState.showAmount">المبلغ</th>
                <th scope="col">
                  <span class="visually-hidden">الإجراءات</span>
                </th>
              </tr>
            </thead>
            <tbody>
              <tr
                ng-repeat="payment in rtlPayments | filter:rtlDataState.query | orderBy:rtlDataState.order"
                animate
              >
                <td class="data-table-select">
                  <input
                    type="checkbox"
                    ng-model="payment.selected"
                    aria-label="تحديد {{ payment.email }}"
                  />
                </td>
                <td ng-if="rtlDataState.showStatus">{{ payment.statusAr }}</td>
                <td ng-if="rtlDataState.showEmail" class="lowercase">
                  {{ payment.email }}
                </td>
                <td ng-if="rtlDataState.showAmount" class="table-cell-medium">
                  {{ payment.amount }}
                </td>
                <td>
                  <button
                    variant="ghost"
                    size="icon-xs"
                    type="button"
                    aria-label="فتح القائمة"
                  >
                    •••
                  </button>
                </td>
              </tr>
              <tr
                ng-if="!(rtlPayments | filter:rtlDataState.query).length"
                animate
              >
                <td colspan="5" class="data-table-empty">لا توجد نتائج.</td>
              </tr>
            </tbody>
          </table>
        </figure>
        <div class="data-table-footer">
          <p>0 من 5 صف(وف) محدد.</p>
          <div class="row">
            <button variant="outline" size="sm" type="button" disabled>
              السابق</button
            ><button variant="outline" size="sm" type="button" disabled>
              التالي
            </button>
          </div>
        </div>
      </section>
      <output class="table-workflow-output">{{ tableState.action }}</output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native tabular structure and header scopes.

Anatomy

Root styling selector

  • table

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
aria-selectedAuthoredSelected item state.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native tabular structure and header scopes. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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

Accessibility

Keep meaningful labels and table or figure structure in authored HTML. Do not rely on color, position, or generated visual marks as the only representation of data.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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

15 - textarea

Multi-line text control with state attributes for empty/required/disabled/error.

Use native textarea controls; AngularCSS styles them directly.

<textarea placeholder="Add a message"></textarea>
<textarea placeholder="Invalid" aria-invalid="true"></textarea>

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 Textarea</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="message='Ship semantic components';rtlMessage='';textareaAction='Ready'"
    data-example="textarea-button textarea-demo textarea-disabled textarea-field textarea-invalid textarea-rtl"
  >
    <main class="visual-example">
      <div class="field">
        <label for="docs-textarea-message">Message</label>
        <textarea
          id="docs-textarea-message"
          placeholder="Add a message"
          ng-model="message"
        ></textarea>
        <p>Add context for your request.</p>
      </div>

      <div class="field">
        <label for="docs-textarea-disabled">Disabled</label>
        <textarea
          id="docs-textarea-disabled"
          placeholder="Disabled"
          disabled
        ></textarea>
      </div>

      <div class="field">
        <label for="docs-textarea-invalid">Invalid</label>
        <textarea
          id="docs-textarea-invalid"
          placeholder="Invalid"
          aria-invalid="true"
        ></textarea>
        <p class="field-error">A message is required.</p>
      </div>

      <div class="textarea-button-demo field">
        <label for="docs-textarea-reply">Reply</label>
        <textarea
          id="docs-textarea-reply"
          placeholder="Type your message here."
        ></textarea>
        <button type="button" ng-click="textareaAction='Message sent'">
          Send message
        </button>
      </div>

      <div dir="rtl" lang="ar" class="field">
        <label for="docs-textarea-rtl">رسالتك</label>
        <textarea
          id="docs-textarea-rtl"
          ng-model="rtlMessage"
          placeholder="اكتب رسالتك هنا."
        ></textarea>
        <p>سيتم إرسال رد إلى بريدك الإلكتروني.</p>
      </div>

      <output class="output textarea-output">
        Message: {{ message ? message : "empty" }} · {{ textareaAction }}
      </output>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Native textarea behavior and AngularTS models.

Anatomy

Root styling selector

  • textarea

Semantic structure

Use semantic HTML with the root styling selector above. Native elements provide the structure; the stylesheet supplies presentation.

API

Attributes and state

AttributeAccessPurpose
aria-invalidAuthoredValidation state exposed to assistive technology and CSS.
disabledAuthoredDisables native or component interaction.
requiredAuthoredMarks a native form value as required.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

This styling hook does not define component-specific CSS custom properties.

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

Native textarea behavior and AngularTS models. AngularCSS supplies styling without a runtime directive. Native HTML owns platform behavior; AngularTS owns application values, commands, and authored state.

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 semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

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