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

Return to the regular view of this page.

Guides

Apply AngularCSS ownership, composition, accessibility, and testing conventions.

These guides cover decisions shared by several components:

  1. AngularTS ownership
  2. Composition
  3. Accessibility
  4. Testing

Read the individual component reference for exact selectors, attributes, state, events, and keyboard behavior.

1 - AngularTS Ownership

Keep models, validation, bindings, and structural behavior in AngularTS instead of duplicating them in components.

AngularCSS extends AngularTS; it does not replace framework behavior. This rule keeps components predictable and prevents two state systems from disagreeing.

AngularTS owns application state

Use AngularTS for values, commands, collections, and conditional rendering:

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

ng-model owns the value while the browser owns the range control. No AngularCSS directive is needed. Use ng-range-slider on a parent only when two or more native range inputs must share one visual track.

Native HTML owns platform behavior

Prefer native controls for text, checkboxes, radios, ranges, selects, progress, tables, and labels. Their form submission, browser validation, autofill, mobile input, and accessibility behavior should remain intact.

Native dialog owns modal focus, Escape closure, background isolation, and focus restoration. Native details and the Popover API own their disclosure behavior. AngularCSS supplies styles for these elements.

AngularCSS owns component mechanics

AngularCSS may manage:

  • Trigger and panel relationships.
  • Composite keyboard navigation and roving focus.
  • Focus movement and restoration for composite widgets that need them.
  • Required ARIA relationships and state when native HTML cannot express them.
  • Component-specific DOM events.

AngularCSS does not own:

  • Interpolation or expression parsing.
  • ng-model, form controllers, or validation rules.
  • ng-if, ng-repeat, or other structural rendering.
  • Routing, data fetching, persistence, or business commands.

Controlled state

Some components observe concise authored attributes such as open, collapsed, or native/ARIA state such as aria-selected. Use AngularTS bindings to update those attributes when application code must control the component. The component reference marks attributes as input, output, or input/output.

Directive names

AngularCSS avoids collisions with AngularTS. Styling-only elements use native HTML and roles, so the switch is input[role="switch"]; AngularTS owns model bindings while the browser owns checkbox state and form behavior.

2 - Composition

Combine small AngularCSS primitives into forms, overlays, date pickers, and application navigation.

AngularCSS components expose HTML parts rather than private templates. Compose them when a workflow needs behavior from more than one primitive.

Form field

Combine field, label, input, description, and AngularTS validation:

<div class="field">
  <label for="email">Email</label>
  <input id="email" name="email" ng-model="profile.email" required />
  <p>Used for account notices.</p>
  <p ng-if="profileForm.email.invalid" class="field-error">
    Enter a valid email.
  </p>
</div>

The native input and AngularTS form controller own the value and validity. The field styles the authored label, helper, and error text around the control.

Date picker

A date picker combines a field, text or date input, popover, and calendar. The calendar emits angularcss:calendar-select; application code converts the day into the required date model and updates the input.

Do not introduce a second hidden date model inside the calendar directive.

Command dialog

Place command content inside a dialog. Dialog owns modal focus and closure; command owns active result navigation; AngularTS owns filtering and command execution.

Disclosure sidebar group

Place native details.disclosure inside a sidebar group. Sidebar owns its global expanded state and responsive hooks; the browser owns nested disclosure.

Composition rules

  1. Assign each state value to one owner.
  2. Preserve semantic elements and authored labels.
  3. Reuse an existing primitive for focus or disclosure behavior.
  4. Connect composed regions with stable IDs and ARIA relationships.
  5. Test the complete workflow, not only each isolated primitive.

3 - Accessibility

Author names and semantics, understand generated ARIA state, and test complete component compositions.

AngularCSS supplies component mechanics, but accessibility depends on the final authored HTML. Every component page documents what the directive generates and what the application must provide.

Start with semantic HTML

Use native elements before adding roles. A button already supports keyboard activation, a label connects to a form control, and a nav exposes a navigation landmark.

Use role only for composite patterns without a suitable native element, such as tabs, menus, and custom listboxes.

Provide accessible names

Visible text should name buttons, fields, landmarks, and overlays. Use aria-label only when visible text cannot provide the name. Dialog-like components should include title and description parts so the directive can connect aria-labelledby and aria-describedby.

Preserve keyboard behavior

  • Tab enters and leaves components in normal document order.
  • Arrow keys move within composite controls when documented.
  • Enter and Space activate buttons and disclosure triggers.
  • Escape closes menus and overlays and restores focus where appropriate.
  • Disabled items are not activated or selected.

Do not use CSS to visually reorder focusable controls independently of their DOM order.

Keep focus visible

Application overrides must retain a visible focus indicator with sufficient contrast. Modal dialogs, alert dialogs, sheets, and drawers trap focus while open and restore focus to the invoking trigger after closure.

Generated state

Directives generate or synchronize ARIA relationships and data-* state. Do not hard-code generated IDs. Authored labels and relationships are preserved when valid, so applications may supply stable IDs for server rendering and tests.

Dynamic feedback

Use status and alert semantics according to urgency. Toasts, spinners, progress, and field errors must not announce the same change through multiple live regions.

Test the composition

For every production component:

  1. Complete the workflow using only a keyboard.
  2. Confirm focus is always visible and restored after overlays close.
  3. Inspect the accessibility tree for names, roles, values, and relationships.
  4. Test validation and dynamic feedback with a screen reader.
  5. Check zoom, reflow, RTL, reduced motion, and high-contrast settings where relevant.

4 - Testing

Run static quality gates, component browser tests, and the complete documentation example suite.

AngularCSS tests the HTML contract in Chromium with Playwright and validates source, public entrypoints, documentation inventory, AngularTS overlap, and forbidden ports with static checks.

Static checks

npm run check

This command verifies TypeScript, canonical component and element entrypoints, generated declarations, documentation completeness, component test inventory, AngularTS directive ownership, CSS isolation, and test ports.

Component tests

PLAYWRIGHT_PORT=4101 npm run test:components -- --reporter=dot

Use an available port other than 3000 or 4000. The default is 4100; set PLAYWRIGHT_PORT when another local service already owns it.

Documentation tests

PLAYWRIGHT_PORT=4101 npm run test:docs -- --reporter=dot

The documentation suite opens every component and element iframe, verifies that local AngularTS and AngularCSS assets load, checks that templates compile, and exercises representative form bindings.

Hugo build

hugo --source docs --destination /tmp/angularcss-docs --cleanDestinationDir

The repository includes precompiled Docsy shell CSS so the site builds with the standard Hugo binary. The module may still report that extended Hugo is its preferred environment; that warning does not require a CDN or prevent the build.

Regenerate component references

npm run generate-docs:components

The generator reads canonical TypeScript implementations and updates selectors, parts, attributes, states, CSS variables, and events on all component pages. npm run check:docs-content fails when generated reference content is stale.

5 - Support

Choose the right channel for AngularCSS questions, defects, proposals, and security reports.

Use GitHub Discussions for integration, HTML composition, and customization questions.

Use the issue tracker for reproducible AngularCSS defects and focused feature proposals. Include:

  • A reduced semantic HTML example.
  • AngularCSS and AngularTS versions.
  • Browser and operating system.
  • Expected and observed behavior.
  • Keyboard or assistive-technology details when relevant.

Report vulnerabilities through the repository’s private GitHub security advisory flow. Do not place security-sensitive details in a public issue.

The compatibility and upgrades page describes supported environments and the latest-version verification command.

6 - Contributing

Change AngularCSS while preserving its HTML-first ownership and public API contracts.

Read the repository contribution guide before opening a pull request. It defines the HTML, AngularTS, CSS, and AngularCSS ownership order, local setup, generated documentation workflow, and public API review process.

For shared presentation changes, update the DTCG 2025.10 source rather than editing generated token CSS. For catalog changes, keep root classes minimal and prefer semantic descendants and native attributes. Browser tests must exercise the built standalone example.

The required local sequence is:

npm run release:build
npm run check
npm test

Keep a pull request focused. Describe the concrete trigger, the resulting behavior, the public API impact, and the validation performed.