Native HTML elements styled directly, without AngularCSS runtime behavior.
This is the multi-page printable view of this section. Click here to print.
Elements
- 1: button
- 2: checkbox
- 3: dialog
- 4: input
- 5: kbd
- 6: label
- 7: progress
- 8: radio-group
- 9: range
- 10: scroll-area
- 11: select
- 12: separator
- 13: switch
- 14: table
- 15: textarea
1 - button
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
| Attribute | Access | Purpose |
|---|---|---|
aria-disabled | Authored | Semantic disabled state. |
aria-haspopup | Authored | Type of popup controlled by the trigger. |
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
icon | Authored | Icon position: inline-start or inline-end. |
size | Authored | Size: xs, sm, default, lg, icon-xs, icon-sm, icon, or icon-lg. |
variant | Authored | Style: 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
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
| Attribute | Access | Purpose |
|---|---|---|
checked | Authored | Initial native checked state. |
disabled | Authored | Disables native or component interaction. |
required | Authored | Marks 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
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
| Attribute | Access | Purpose |
|---|---|---|
closedby | Authored | Native dialog dismissal behavior. |
command | Authored | Native invoker action such as show-modal or close. |
commandfor | Authored | ID of the native dialog controlled by an invoker. |
dir | Authored | Text and interaction direction: ltr or rtl. |
size | Authored | Dialog 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
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
| Attribute | Access | Purpose |
|---|---|---|
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
disabled | Authored | Disables native or component interaction. |
size | Authored | Native number of visible characters; also enables content sizing when supported. |
type | Authored | Native 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
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
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
| Attribute | Access | Purpose |
|---|---|---|
for | Authored | ID 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
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
| Attribute | Access | Purpose |
|---|---|---|
dir | Authored | Text and interaction direction: ltr or rtl. |
max | Authored | Maximum native or component value. |
value | Authored | Native 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
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 & 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
| Attribute | Access | Purpose |
|---|---|---|
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
checked | Authored | Initial native checked state. |
dir | Authored | Text and interaction direction: ltr or rtl. |
disabled | Authored | Disables native or component interaction. |
name | Authored | Authored HTML attribute or styling hook. |
required | Authored | Marks a native form value as required. |
value | Authored | Native 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
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
| Attribute | Access | Purpose |
|---|---|---|
disabled | Authored | Disables native or component interaction. |
max | Authored | Maximum native or component value. |
min | Authored | Minimum native or component value. |
orientation | Authored | Layout direction: horizontal or vertical. |
step | Authored | Native numeric step interval. |
value | Authored | Native 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
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
| Attribute | Access | Purpose |
|---|---|---|
dir | Authored | Text and interaction direction: ltr or rtl. |
tabindex | Authored | Use 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
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
| Attribute | Access | Purpose |
|---|---|---|
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
dir | Authored | Text and interaction direction: ltr or rtl. |
disabled | Authored | Disables native or component interaction. |
multiple | Authored | Allows more than one item to remain selected or open. |
name | Authored | Authored HTML attribute or styling hook. |
required | Authored | Marks a native form value as required. |
size | Authored | Visual 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
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 & security</span></div>
<hr aria-orientation="vertical" />
<div><strong>Help</strong><span>Support & 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
| Attribute | Access | Purpose |
|---|---|---|
aria-orientation | Authored | Separator 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
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
| Attribute | Access | Purpose |
|---|---|---|
checked | Authored | Initial native checked state. |
disabled | Authored | Disables native or component interaction. |
required | Authored | Marks a native form value as required. |
role | Authored | Explicit semantic role when native HTML does not provide one. |
size | Authored | Switch 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
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
| Attribute | Access | Purpose |
|---|---|---|
aria-selected | Authored | Selected 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
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
| Attribute | Access | Purpose |
|---|---|---|
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
disabled | Authored | Disables native or component interaction. |
required | Authored | Marks 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.