tabs

Tabbed content sections

Add ng-tabs to a section, place native buttons in its list, and follow the list with direct semantic section or article panels. The directive assigns tab roles, relationships, selection state, and keyboard navigation.

<section ng-tabs>
  <menu>
    <button aria-selected="true">Overview</button>
  </menu>
  <section>Content</section>
</section>

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 Tabs</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="tabs-demo">
    <section ng-tabs>
      <menu aria-label="Project sections">
        <button aria-selected="true">Overview</button>
        <button>Analytics</button>
        <button>Reports</button>
        <button>Settings</button>
      </menu>
      <article>
        <header>
          <h2>Overview</h2>
          <p>
            View your key metrics and recent project activity. Track progress
            across all your active projects.
          </p>
        </header>
        <section class="muted">
          You have 12 active projects and 3 pending tasks.
        </section>
      </article>
      <article>
        <header>
          <h2>Analytics</h2>
          <p>
            Track performance and user engagement metrics. Monitor trends and
            identify growth opportunities.
          </p>
        </header>
        <section class="muted">
          Page views are up 25% compared to last month.
        </section>
      </article>
      <article>
        <header>
          <h2>Reports</h2>
          <p>
            Generate and download your detailed reports. Export data in multiple
            formats for analysis.
          </p>
        </header>
        <section class="muted">
          You have 5 reports ready and available to export.
        </section>
      </article>
      <article>
        <header>
          <h2>Settings</h2>
          <p>
            Manage your account preferences and options. Customize your
            experience to fit your needs.
          </p>
        </header>
        <section class="muted">
          Configure notifications, security, and themes.
        </section>
      </article>
    </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 Tabs 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="advancedVisible = false; overviewDisabled = false"
    data-example="tabs-disabled tabs-icons tabs-line tabs-rtl tabs-vertical"
  >
    <main class="tabs-workflows visual-example">
      <section aria-labelledby="tabs-dynamic-heading">
        <header>
          <h2 id="tabs-dynamic-heading">Dynamic sections</h2>
          <button
            type="button"
            variant="outline"
            size="sm"
            ng-click="advancedVisible = !advancedVisible"
          >
            {{ advancedVisible ? 'Remove advanced' : 'Add advanced' }}
          </button>
        </header>
        <section ng-tabs id="dynamic-tabs">
          <menu aria-label="Dynamic project sections">
            <button aria-selected="true">Overview</button>
            <button>Activity</button>
            <button ng-if="advancedVisible">Advanced</button>
          </menu>
          <section>Project overview</section>
          <section>Recent project activity</section>
          <section ng-if="advancedVisible">Advanced project controls</section>
        </section>
      </section>

      <section aria-labelledby="tabs-disabled-heading">
        <header>
          <h2 id="tabs-disabled-heading">Disabled state</h2>
          <button
            type="button"
            variant="outline"
            size="sm"
            ng-click="overviewDisabled = !overviewDisabled"
          >
            {{ overviewDisabled ? 'Enable overview' : 'Disable overview' }}
          </button>
        </header>
        <section ng-tabs id="disabled-tabs">
          <menu aria-label="Account sections">
            <button aria-selected="true" ng-disabled="overviewDisabled">
              Overview
            </button>
            <button>Settings</button>
            <button disabled>Unavailable</button>
          </menu>
          <section>Account overview</section>
          <section>Account settings</section>
          <section>Unavailable settings</section>
        </section>
      </section>

      <section aria-labelledby="tabs-vertical-heading">
        <header><h2 id="tabs-vertical-heading">Vertical</h2></header>
        <section ng-tabs orientation="vertical" id="vertical-tabs">
          <menu aria-label="Preference sections">
            <button aria-selected="true">Account</button>
            <button>Password</button>
            <button>Notifications</button>
          </menu>
          <section>Account preferences</section>
          <section>Password preferences</section>
          <section>Notification preferences</section>
        </section>
      </section>

      <section aria-labelledby="tabs-variants-heading">
        <header><h2 id="tabs-variants-heading">Variants</h2></header>
        <div class="tabs-variant-stack">
          <section ng-tabs id="icon-tabs">
            <menu aria-label="Editor view">
              <button aria-selected="true">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  aria-hidden="true"
                >
                  <rect x="3" y="4" width="18" height="16" rx="2" />
                  <path d="M3 9h18" />
                </svg>
                Preview
              </button>
              <button>
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  aria-hidden="true"
                >
                  <path d="m8 9-3 3 3 3M16 9l3 3-3 3" />
                </svg>
                Code
              </button>
            </menu>
          </section>
          <section ng-tabs id="line-tabs">
            <menu variant="line" aria-label="Report sections">
              <button aria-selected="true">Overview</button>
              <button>Analytics</button>
              <button>Reports</button>
            </menu>
          </section>
        </div>
      </section>

      <section aria-labelledby="tabs-rtl-heading" dir="rtl" lang="ar">
        <header><h2 id="tabs-rtl-heading">الاتجاه من اليمين</h2></header>
        <section ng-tabs id="rtl-tabs">
          <menu aria-label="أقسام المشروع">
            <button>نظرة عامة</button>
            <button aria-selected="true">التحليلات</button>
            <button>التقارير</button>
          </menu>
          <section>نظرة عامة على المشروع</section>
          <section>تحليلات المشروع</section>
          <section>تقارير المشروع</section>
        </section>
      </section>
    </main>
  </body>
</html>

Installation

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

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

Anatomy

Directive selectors

  • ng-tabs

Semantic structure

Use native elements for authored structure. Component classes are optional visual hooks when an HTML relationship is not specific enough.

API

Attributes and state

AttributeAccessPurpose
aria-controlsOutputID of the element controlled by a trigger.
aria-hiddenOutputWhether generated or collapsed content is hidden from assistive technology.
aria-labelledbyOutputID of the element that supplies the accessible name.
aria-orientationInput/outputInteraction axis exposed to assistive technology.
aria-selectedInput/outputSelected item state.
dirInputText and interaction direction: ltr or rtl.
orientationInput/outputLayout direction: horizontal or vertical.
roleOutputExplicit semantic role when native HTML does not provide one.
tabindexOutputKeyboard focus order for composite descendants.

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

CSS custom properties

This directive does not write 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 directive supplies navigation semantics and keyboard state where required. URLs, routing, current-page state, and navigation side effects remain application-owned.

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

Accessibility

Use semantic navigation landmarks and links. Expose the current destination with aria-current and keep keyboard order consistent with visual order.

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

Customization

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

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