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.