Small semantic HTML compositions built from native elements and CSS.
This is the multi-page printable view of this section. Click here to print.
Patterns
- 1: accordion
- 2: alert
- 3: aspect-ratio
- 4: avatar
- 5: badge
- 6: breadcrumb
- 7: button-group
- 8: card
- 9: chart
- 10: description-list
- 11: disclosure
- 12: empty
- 13: field
- 14: file-upload
- 15: filter-bar
- 16: input-group
- 17: input-otp
- 18: item
- 19: pagination
- 20: popover
- 21: skeleton
- 22: spinner
- 23: stepper
- 24: toggle
- 25: toggle-group
- 26: validation-summary
1 - accordion
Use an accessibly named section around native details elements. Give
sibling items the same name when opening one item should close the others.
The semantic structure needs no component class.
<section aria-label="Sections">
<details name="sections" open>
<summary>Section 1</summary>
<div>Content for section 1</div>
</details>
</section>
Omit name to allow more than one section to remain open.
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 Accordion</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="accordion-demo">
<section class="visual-example" aria-label="Shipping questions">
<details name="shipping-questions" open>
<summary>What are your shipping options?</summary>
<div>
We offer standard (5-7 days), express (2-3 days), and overnight
shipping. Free shipping on international orders.
</div>
</details>
<details name="shipping-questions">
<summary>What is your return policy?</summary>
<div>
Returns are accepted within 30 days. Items must be unused and in their
original packaging.
</div>
</details>
<details name="shipping-questions">
<summary>How can I contact customer support?</summary>
<div>Reach us by email, live chat, or phone during business hours.</div>
</details>
</section>
</body>
</html>
State Variants
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Accordion State 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="accordion-basic accordion-disabled accordion-multiple"
>
<main class="accordion-workflow-grid">
<section
class="accordion-workflow-section"
aria-labelledby="accordion-basic-title"
>
<h2 id="accordion-basic-title">Account help</h2>
<section aria-label="Account help questions">
<details name="account-help" open>
<summary>How do I reset my password?</summary>
<div>
Click Forgot Password on the login page, enter your email address,
and we'll send you a reset link that expires in 24 hours.
</div>
</details>
<details name="account-help">
<summary>Can I change my subscription plan?</summary>
<div>
You can upgrade or downgrade your plan at any time from your
account settings.
</div>
</details>
<details name="account-help">
<summary>What payment methods do you accept?</summary>
<div>We accept major credit cards, PayPal, and bank transfers.</div>
</details>
</section>
</section>
<section
class="accordion-workflow-section"
aria-labelledby="accordion-disabled-title"
>
<h2 id="accordion-disabled-title">Availability</h2>
<section aria-label="Feature availability questions">
<details name="availability">
<summary>Can I access my account history?</summary>
<div>
Your complete account history is available from the dashboard.
</div>
</details>
<details name="availability" inert>
<summary>Premium feature information</summary>
<div>Upgrade your plan to access premium feature information.</div>
</details>
<details name="availability">
<summary>How do I update my email address?</summary>
<div>
Update it in account settings and confirm the verification email.
</div>
</details>
</section>
</section>
<section
class="accordion-workflow-section accordion-workflow-wide"
aria-labelledby="accordion-multiple-title"
>
<h2 id="accordion-multiple-title">Settings</h2>
<section aria-label="Settings questions">
<details open>
<summary>Notification Settings</summary>
<div>
Choose email alerts or push notifications for mobile devices.
</div>
</details>
<details>
<summary>Privacy & Security</summary>
<div>
Enable two-factor authentication, review active sessions, and
configure data sharing.
</div>
</details>
<details>
<summary>Billing & Subscription</summary>
<div>View your plan, payment history, and upcoming invoices.</div>
</details>
</section>
</section>
</main>
</body>
</html>
Layout Variants
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Accordion Layout 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="accordion-borders accordion-card accordion-rtl"
>
<main class="accordion-workflow-grid accordion-layout-workflows">
<section
class="accordion-workflow-section"
aria-labelledby="accordion-borders-title"
>
<h2 id="accordion-borders-title">Billing questions</h2>
<section class="accordion-bordered" aria-label="Billing questions">
<details name="billing" open>
<summary>How does billing work?</summary>
<div>
Billing is charged at the beginning of each monthly or annual
cycle, and you can cancel anytime.
</div>
</details>
<details name="billing">
<summary>Is my data secure?</summary>
<div>
Data is encrypted at rest and in transit using industry-standard
protocols.
</div>
</details>
<details name="billing">
<summary>What integrations do you support?</summary>
<div>
Connect popular tools or build custom integrations with our API.
</div>
</details>
</section>
</section>
<article
class="accordion-card-demo card"
aria-labelledby="accordion-card-title"
>
<header>
<h2 id="accordion-card-title">Subscription & Billing</h2>
<p>Common questions about plans, payments, and cancellations.</p>
</header>
<section>
<section aria-label="Subscription and billing questions">
<details name="subscription" open>
<summary>What subscription plans do you offer?</summary>
<div>
Choose Starter, Professional, or Enterprise based on storage,
API, and support needs.
</div>
</details>
<details name="subscription">
<summary>How does billing work?</summary>
<div>
Billing occurs automatically at the start of each cycle.
</div>
</details>
<details name="subscription">
<summary>How do I cancel my subscription?</summary>
<div>
Cancel from account settings with access through the current
billing period.
</div>
</details>
</section>
</section>
</article>
<section
class="accordion-workflow-section accordion-workflow-wide"
dir="rtl"
lang="ar"
aria-labelledby="accordion-rtl-title"
>
<h2 id="accordion-rtl-title">الأسئلة الشائعة</h2>
<section aria-label="الأسئلة الشائعة">
<details name="arabic-faq" open>
<summary>كيف يمكنني إعادة تعيين كلمة المرور؟</summary>
<div>
انقر على نسيت كلمة المرور في صفحة تسجيل الدخول، وسنرسل لك رابطًا
لإعادة تعيينها.
</div>
</details>
<details name="arabic-faq">
<summary>هل يمكنني تغيير خطة الاشتراك الخاصة بي؟</summary>
<div>يمكنك ترقية خطتك أو تخفيضها في أي وقت من إعدادات الحساب.</div>
</details>
<details name="arabic-faq">
<summary>ما هي طرق الدفع التي تقبلونها؟</summary>
<div>نقبل بطاقات الائتمان وPayPal والتحويلات المصرفية.</div>
</details>
</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. Named native details disclosures.
Anatomy
Root styling selector
section[aria-label]:has(> details)
Semantic structure
Use an accessibly named section around direct details children. Each item requires a direct summary followed by authored content. Apply the same name to sibling details for exclusive disclosure.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
inert | Authored | Prevents interaction while the component is hidden. |
name | Authored | Authored HTML attribute or styling hook. |
open | Authored | Initial or controlled open 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 details and summary own disclosure, focus, and keyboard behavior. Give sibling details the same name for an exclusive accordion, or omit name when several panels may remain open. AngularCSS registers no accordion directive.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use a direct summary as the accessible trigger for each details item. The browser exposes disclosure state and keyboard activation. Use inert only when an entire unavailable disclosure must be removed from interaction.
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 - alert
Use section[role="alert"] for important feedback blocks. The default presentation is
neutral; add variant="destructive" for destructive feedback or override the
AngularCSS color tokens for application-specific colors.
<section role="alert">
<svg aria-hidden="true"><!-- optional icon --></svg>
<h2>Saved!</h2>
<p>Your profile was updated.</p>
<div>
<button ng-click="dismiss()">Dismiss</button>
</div>
</section>
Example
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Alert</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="alert-demo">
<div class="visual-example">
<section aria-live="assertive" aria-atomic="true" role="alert">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="12" r="10"></circle>
<path d="M9 12l2 2 4-4"></path>
</svg>
<h2>Payment successful</h2>
<p>
Your payment of $29.99 has been processed. A receipt has been sent to
your email address.
</p>
</section>
<section aria-live="assertive" aria-atomic="true" role="alert">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4" />
<path d="M12 8h.01" />
</svg>
<h2>New feature available</h2>
<p>
We've added dark mode support. You can enable it in your account
settings.
</p>
</section>
</div>
</body>
</html>
Variants And Composition
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Alert 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="darkModeEnabled=false"
data-example="alert-action alert-basic alert-colors alert-destructive alert-rtl"
>
<main class="alert-workflow-grid">
<section role="alert">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none">
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="2"
/>
<path
d="m9 12 2 2 4-4"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<h2>Account updated successfully</h2>
<p>
Your profile information has been saved. Changes will be reflected
immediately.
</p>
</section>
<section aria-live="polite" role="alert">
<h2>Dark mode is now available</h2>
<p>Enable it under your profile settings to get started.</p>
<button
size="xs"
type="button"
ng-click="darkModeEnabled=true"
ng-disabled="darkModeEnabled"
>
{{ darkModeEnabled ? 'Enabled' : 'Enable' }}
</button>
</section>
<section variant="warning" role="alert">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none">
<path
d="M10.3 2.9 1.8 17a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 2.9a2 2 0 0 0-3.4 0Z"
stroke="currentColor"
stroke-width="2"
stroke-linejoin="round"
/>
<path
d="M12 9v4M12 17h.01"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<h2>Your subscription will expire in 3 days.</h2>
<p>
Renew now to avoid service interruption or upgrade to a paid plan.
</p>
</section>
<section variant="destructive" role="alert">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none">
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="2"
/>
<path
d="M12 8v4M12 16h.01"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<h2>Payment failed</h2>
<p>
Your payment could not be processed. Check your payment method and try
again.
</p>
</section>
<section
class="alert-rtl-demo"
dir="rtl"
lang="ar"
aria-label="التنبيهات"
>
<section role="alert">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none">
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="2"
/>
<path
d="m9 12 2 2 4-4"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<h2>تم الدفع بنجاح</h2>
<p>تمت معالجة دفعتك وإرسال إيصال إلى عنوان بريدك الإلكتروني.</p>
</section>
<section role="alert">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none">
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="2"
/>
<path
d="M12 16v-4M12 8h.01"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<h2>ميزة جديدة متاحة</h2>
<p>لقد أضفنا دعم الوضع الداكن ويمكنك تفعيله في إعدادات حسابك.</p>
</section>
</section>
<output class="output alert-workflow-output">
Dark mode: {{ darkModeEnabled ? 'enabled' : 'disabled' }}
</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. Semantic authored status content.
Anatomy
Root styling selector
[role="alert"]
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-atomic | Authored | Whether an assistive technology announces the entire updated region. |
aria-live | Authored | Announcement priority for updates to a live region. |
role | Authored | Explicit semantic role when native HTML does not provide one. |
variant | Authored | Status presentation: info, success, warning, or destructive; omit for the default presentation. |
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
Semantic authored status content. 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 the appropriate live-region or status semantics for dynamic feedback. Decorative feedback must stay hidden from assistive technology.
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 - aspect-ratio
Set ratio on a figure and optionally override --ratio. Direct images,
videos, and iframes fill the figure with object-fit: cover; applications may
override that fit when media should not crop.
<figure ratio="16 / 9">
<img src="photo.jpg" alt="Photo" />
</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 Aspect Ratio</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="aspect-ratio-demo">
<figure ratio="16 / 9" class="visual-example">
<img src="../../images/avatars/01.png" alt="Photo" />
</figure>
</body>
</html>
Ratios And Direction
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Aspect Ratio 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="aspect-ratio-portrait aspect-ratio-rtl aspect-ratio-square"
>
<main class="aspect-ratio-workflows">
<figure
ratio="9 / 16"
class="aspect-ratio-portrait"
aria-label="Portrait aspect ratio"
>
<img src="../../images/avatars/01.png" alt="Photo" />
</figure>
<figure
ratio="1 / 1"
class="aspect-ratio-square"
aria-label="Square aspect ratio"
>
<img src="../../images/avatars/01.png" alt="Photo" />
</figure>
<figure class="aspect-ratio-rtl" dir="rtl" lang="ar">
<figure ratio="16 / 9" aria-label="Landscape aspect ratio">
<img src="../../images/avatars/01.png" alt="صورة" />
</figure>
<figcaption>منظر طبيعي جميل</figcaption>
</figure>
</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. CSS aspect-ratio layout.
Anatomy
Root styling selector
figure[ratio]
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 |
|---|---|---|
ratio | Authored | Aspect ratio: 1 / 1, 9 / 16, or 16 / 9; defaults to 16 / 9. |
Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.
CSS custom properties
| Variable | Purpose |
|---|---|
--ratio | Rendered aspect ratio; defaults to 16 / 9. |
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
CSS aspect-ratio layout. 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.
4 - avatar
Use .avatar with a native image or authored fallback, plus an optional badge.
Place adjacent avatars and a native output in one wrapper to form a group.
<span class="avatar" aria-label="Jane Doe">
<span>JD</span>
<output></output>
</span>
<span>
<span class="avatar"><img src="avatar.jpg" alt="Alex Brown" /></span>
<output>+3</output>
</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 Avatar</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="avatar-badge avatar-basic avatar-demo avatar-group avatar-group-count"
>
<div class="visual-example">
<span class="avatar">
<img
class="avatar-grayscale"
src="../../images/avatars/01.png"
alt="Profile portrait"
/>
<span>CN</span>
</span>
<span class="avatar">
<img src="../../images/avatars/02.png" alt="Profile portrait" />
<span>ER</span>
<output variant="success"></output>
</span>
<span class="avatar" aria-label="Jane Doe">
<span>JD</span>
</span>
<span class="avatar-grayscale">
<span class="avatar">
<img src="../../images/avatars/01.png" alt="Profile portrait" />
<span>CN</span>
</span>
<span class="avatar">
<img src="../../images/avatars/03.png" alt="Profile portrait" />
<span>LR</span>
</span>
<span class="avatar">
<img src="../../images/avatars/04.png" alt="Profile portrait" />
<span>ER</span>
</span>
<output>+3</output>
</span>
</div>
</body>
</html>
Variants And Composition
Use size="sm", the default size, or size="lg". Badge icons, grouped counts,
RTL layouts, and dropdown triggers compose from the same semantic parts without
changing Avatar 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 Avatar 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="avatarAction = 'None'"
data-example="avatar-badge-icon avatar-dropdown avatar-group-count-icon avatar-rtl avatar-size"
>
<main class="avatar-workflows">
<section
class="avatar-workflow-section"
aria-labelledby="avatar-badge-heading"
>
<h2 id="avatar-badge-heading">Badge icon</h2>
<div class="avatar-workflow-row" aria-label="Avatar badge icon">
<span class="avatar">
<img
class="avatar-grayscale"
src="../../images/avatars/02.png"
alt="@pranathip"
/>
<span>PP</span>
<output>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
aria-hidden="true"
>
<path d="M5 12h14" />
<path d="M12 5v14" />
</svg>
</output>
</span>
</div>
</section>
<section
class="avatar-workflow-section"
aria-labelledby="avatar-count-heading"
>
<h2 id="avatar-count-heading">Group count icon</h2>
<div class="avatar-grayscale" aria-label="Avatar group count icon">
<span class="avatar">
<img src="../../images/avatars/01.png" alt="@angularcss" />
<span>CN</span>
</span>
<span class="avatar">
<img src="../../images/avatars/03.png" alt="@maxleiter" />
<span>LR</span>
</span>
<span class="avatar">
<img src="../../images/avatars/04.png" alt="@evilrabbit" />
<span>ER</span>
</span>
<output>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
aria-hidden="true"
>
<path d="M5 12h14" />
<path d="M12 5v14" />
</svg>
</output>
</div>
</section>
<section
class="avatar-workflow-section"
aria-labelledby="avatar-size-heading"
>
<h2 id="avatar-size-heading">Sizes</h2>
<div
class="avatar-workflow-row avatar-grayscale"
aria-label="Avatar sizes"
>
<span size="sm" class="avatar">
<img src="../../images/avatars/01.png" alt="@angularcss small" />
<span>CN</span>
</span>
<span class="avatar">
<img src="../../images/avatars/01.png" alt="@angularcss default" />
<span>CN</span>
</span>
<span size="lg" class="avatar">
<img src="../../images/avatars/01.png" alt="@angularcss large" />
<span>CN</span>
</span>
</div>
</section>
<section
class="avatar-workflow-section avatar-dropdown-stage"
aria-labelledby="avatar-menu-heading"
>
<h2 id="avatar-menu-heading">Dropdown</h2>
<div ng-dropdown-menu>
<button
type="button"
variant="ghost"
size="icon"
class="avatar-dropdown-trigger"
aria-label="Open user menu"
>
<span class="avatar">
<img src="../../images/avatars/01.png" alt="AngularCSS" />
<span>CN</span>
</span>
</button>
<menu style="--menu-width: 8rem">
<section>
<button ng-click="avatarAction = 'Profile'">Profile</button>
<button ng-click="avatarAction = 'Billing'">Billing</button>
<button ng-click="avatarAction = 'Settings'">Settings</button>
</section>
<hr />
<section>
<button variant="destructive" ng-click="avatarAction = 'Log out'">
Log out
</button>
</section>
</menu>
</div>
<output class="avatar-workflow-output">
Selected: {{ avatarAction }}
</output>
</section>
<section
class="avatar-workflow-section avatar-workflow-wide"
aria-labelledby="avatar-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="avatar-rtl-heading">اتجاه من اليمين إلى اليسار</h2>
<div
class="avatar-workflow-row avatar-rtl-demo"
aria-label="صور رمزية من اليمين إلى اليسار"
>
<span class="avatar">
<img
class="avatar-grayscale"
src="../../images/avatars/01.png"
alt="@angularcss"
/>
<span>CN</span>
</span>
<span class="avatar-rtl-badge avatar">
<img src="../../images/avatars/04.png" alt="@evilrabbit" />
<span>ER</span>
<output variant="success"></output>
</span>
<span class="avatar-grayscale">
<span class="avatar">
<img src="../../images/avatars/01.png" alt="@angularcss" />
<span>CN</span>
</span>
<span class="avatar">
<img src="../../images/avatars/03.png" alt="@maxleiter" />
<span>LR</span>
</span>
<span class="avatar">
<img src="../../images/avatars/04.png" alt="@evilrabbit" />
<span>ER</span>
</span>
<output>+٣</output>
</span>
</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 image and fallback composition.
Anatomy
Root styling selector
.avatar
Semantic structure
Apply .avatar to a wrapper containing either an image or authored fallback content. Badges are optional. Place adjacent avatars and a native output for the remaining count in one div or span; AngularCSS recognizes that group from its structure.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
size | Authored | Avatar size: sm or lg; omit for the default size. |
variant | Authored | Optional direct output badge status: success; omit for the primary status color. |
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
Avatar is a styling-only authored HTML pattern. Native img loading and alternative text remain browser behavior; use a fallback-only avatar when no image is available, or AngularTS structural directives when application state chooses between sources.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Give meaningful portrait images useful alternative text. Give fallback-only avatars an accessible name when initials are ambiguous, and keep decorative status badges out of repeated announcements.
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 - badge
Use class="badge" on an inline element and set variant for appearance.
<span class="badge">Default</span>
<span variant="secondary" class="badge">Secondary</span>
<span variant="outline" class="badge">Outline</span>
For user-selected colors, use variant="custom" and set --badge-background.
Browsers with contrast-color() choose a black or white foreground; set
--badge-foreground when the application requires a specific contrast result.
<span variant="custom" class="badge" style="--badge-background: var(--cyan-9)">
Custom
</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 Badge</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="badge-demo">
<div class="row visual-example">
<span class="badge">Badge</span>
<span variant="secondary" class="badge">Secondary</span>
<span variant="destructive" class="badge">Destructive</span>
<span variant="outline" class="badge">Outline</span>
<span
variant="custom"
class="badge"
style="--badge-background: var(--cyan-9)"
>
Custom
</span>
</div>
</body>
</html>
Composition 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 Badge 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="badge-colors badge-icon badge-link badge-rtl badge-spinner badge-variants"
>
<main class="workflow-stack">
<div class="workflow-row" aria-label="Badge variants">
<span class="badge">Default</span>
<span variant="secondary" class="badge">Secondary</span>
<span variant="destructive" class="badge">Destructive</span>
<span variant="outline" class="badge">Outline</span>
<span variant="ghost" class="badge">Ghost</span>
</div>
<div class="workflow-row" aria-label="Badge custom colors">
<span class="badge-color-blue badge">Blue</span>
<span class="badge-color-green badge">Green</span>
<span class="badge-color-sky badge">Sky</span>
<span class="badge-color-purple badge">Purple</span>
<span class="badge-color-red badge">Red</span>
</div>
<div class="workflow-row" aria-label="Badges with icons">
<span variant="secondary" class="badge">
<svg
icon="inline-start"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path
d="m9 12 2 2 4-4M12 3l2.2 1.5 2.7-.1.8 2.6 2.2 1.5-.9 2.5.9 2.5-2.2 1.5-.8 2.6-2.7-.1L12 21l-2.2-1.5-2.7.1-.8-2.6L4.1 15l.9-2.5-.9-2.5L6.3 7l.8-2.6 2.7.1L12 3Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
Verified
</span>
<span variant="outline" class="badge">
Bookmark
<svg
icon="inline-end"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path
d="M6 4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18l-6-4-6 4V4Z"
stroke="currentColor"
stroke-width="2"
stroke-linejoin="round"
/>
</svg>
</span>
<a href="#link" class="badge">
Open Link
<svg
icon="inline-end"
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>
</a>
</div>
<div class="workflow-row" aria-label="Badges with loading status">
<span variant="destructive" class="badge">
<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>
Deleting
</span>
<span variant="secondary" class="badge">
Generating
<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>
</span>
</div>
<div class="workflow-row" dir="rtl" aria-label="RTL badges">
<span class="badge">شارة</span>
<span variant="secondary" class="badge">ثانوي</span>
<span variant="destructive" class="badge">مدمر</span>
<span variant="outline" class="badge">مخطط</span>
</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. Styled inline authored content.
Anatomy
Root styling selector
.badge
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 |
|---|---|---|
icon | Authored | Direct icon position: inline-start or inline-end. |
variant | Authored | Presentation: default, secondary, destructive, outline, ghost, or custom. |
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
Styled inline authored content. 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 the appropriate live-region or status semantics for dynamic feedback. Decorative feedback must stay hidden from assistive technology.
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 - breadcrumb
Use a .breadcrumb navigation landmark with a native ordered list, links,
separators, and aria-current="page" for the current location. The class
distinguishes the trail from other navigation landmarks.
<nav aria-label="breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#">Home</a>
</li>
<li aria-hidden="true">/</li>
<li>
<span aria-current="page">Docs</span>
</li>
</ol>
</nav>
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 Breadcrumb</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="breadcrumb-basic breadcrumb-link"
>
<nav aria-label="breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#">Home</a>
</li>
<li aria-hidden="true">/</li>
<li>
<a href="#">Components</a>
</li>
<li aria-hidden="true">/</li>
<li>
<span aria-current="page">Breadcrumb</span>
</li>
</ol>
</nav>
</body>
</html>
Variants And Composition
Empty separator and ellipsis parts receive their standard icons. Author custom separator content directly, and compose dropdowns with the existing semantic Dropdown component.
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Breadcrumb 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="breadcrumbSelection = 'None'; rtlBreadcrumbSelection = 'لا شيء'"
data-example="breadcrumb-demo breadcrumb-dropdown breadcrumb-ellipsis breadcrumb-rtl breadcrumb-separator"
>
<main>
<section aria-labelledby="breadcrumb-separator-heading">
<h2 id="breadcrumb-separator-heading">Custom separator</h2>
<nav aria-label="Custom separator breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#home">Home</a>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<a href="#components">Components</a>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<span aria-current="page" aria-disabled="true">Breadcrumb</span>
</li>
</ol>
</nav>
</section>
<section aria-labelledby="breadcrumb-ellipsis-heading">
<h2 id="breadcrumb-ellipsis-heading">Ellipsis</h2>
<nav aria-label="Ellipsis breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#home">Home</a>
</li>
<li aria-hidden="true"></li>
<li>
<span aria-hidden="true">...</span>
</li>
<li aria-hidden="true"></li>
<li>
<a href="#components">Components</a>
</li>
<li aria-hidden="true"></li>
<li>
<span aria-current="page" aria-disabled="true">Breadcrumb</span>
</li>
</ol>
</nav>
</section>
<section aria-labelledby="breadcrumb-demo-heading">
<h2 id="breadcrumb-demo-heading">Collapsed trail</h2>
<nav aria-label="Collapsed breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#home">Home</a>
</li>
<li aria-hidden="true"></li>
<li>
<span ng-dropdown-menu>
<button
type="button"
variant="ghost"
size="icon-sm"
aria-label="Toggle breadcrumb menu"
>
<span aria-hidden="true">...</span>
</button>
<menu>
<section>
<button ng-click="breadcrumbSelection = 'Documentation'">
Documentation
</button>
<button ng-click="breadcrumbSelection = 'Themes'">
Themes
</button>
<button ng-click="breadcrumbSelection = 'GitHub'">
GitHub
</button>
</section>
</menu>
</span>
</li>
<li aria-hidden="true"></li>
<li>
<a href="#components">Components</a>
</li>
<li aria-hidden="true"></li>
<li>
<span aria-current="page" aria-disabled="true">Breadcrumb</span>
</li>
</ol>
</nav>
<output> Selected: {{ breadcrumbSelection }} </output>
</section>
<section aria-labelledby="breadcrumb-dropdown-heading">
<h2 id="breadcrumb-dropdown-heading">Dropdown</h2>
<nav aria-label="Dropdown breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="#home">Home</a>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<span ng-dropdown-menu>
<button type="button">
Components
<svg
icon="inline-end"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="m6 9 6 6 6-6" />
</svg>
</button>
<menu>
<section>
<button>Documentation</button>
<button>Themes</button>
<button>GitHub</button>
</section>
</menu>
</span>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<span aria-current="page" aria-disabled="true">Breadcrumb</span>
</li>
</ol>
</nav>
</section>
<section aria-labelledby="breadcrumb-rtl-heading" dir="rtl" lang="ar">
<h2 id="breadcrumb-rtl-heading">اتجاه من اليمين إلى اليسار</h2>
<nav aria-label="مسار التنقل" class="breadcrumb">
<ol>
<li>
<a href="#home">الرئيسية</a>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<span ng-dropdown-menu>
<button type="button">
المكونات
<svg
icon="inline-end"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="m6 9 6 6 6-6" />
</svg>
</button>
<menu>
<section>
<button ng-click="rtlBreadcrumbSelection = 'التوثيق'">
التوثيق
</button>
<button ng-click="rtlBreadcrumbSelection = 'السمات'">
السمات
</button>
<button ng-click="rtlBreadcrumbSelection = 'جيت هاب'">
جيت هاب
</button>
</section>
</menu>
</span>
</li>
<li aria-hidden="true">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="2.5" />
</svg>
</li>
<li>
<span aria-current="page" aria-disabled="true">مسار التنقل</span>
</li>
</ol>
</nav>
<output> المحدد: {{ rtlBreadcrumbSelection }} </output>
</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 navigation and list composition.
Anatomy
Root styling selector
.breadcrumb
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-current | Authored | Current item or date state. |
dir | Authored | Text and interaction direction: ltr or rtl. |
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 navigation and list composition. 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 semantic navigation landmarks and links. Expose the current destination with aria-current and keep keyboard order consistent with visual order.
Authored accessible names and relationships are preserved. Test the final composition with keyboard navigation and assistive technology because labels and content come from the application.
Customization
Target 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 - button-group
Use fieldset[role="group"] around related commands or form controls. Set
orientation="vertical" for stacked groups. Use Toggle Group when the controls
represent one or more selectable values.
<fieldset role="group">
<button>One</button>
<hr />
<button>Two</button>
</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 Button 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="buttonGroupAction = 'None'"
data-example="button-group-demo button-group-orientation separator button-group-size button-group-split"
>
<main class="visual-example">
<section aria-label="Button group sizes">
<div aria-label="State ownership" role="group">
<button
id="button-group-unmanaged"
type="button"
variant="outline"
size="sm"
>
Small
</button>
<button
id="button-group-managed"
type="button"
variant="outline"
size="sm"
aria-pressed="true"
>
Button
</button>
<button type="button" variant="outline" size="sm">Group</button>
<button
type="button"
variant="outline"
size="icon-sm"
aria-label="Add small"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
</div>
<div role="group">
<button type="button" variant="outline">Default</button>
<button type="button" variant="outline">Button</button>
<button type="button" variant="outline">Group</button>
<button
type="button"
variant="outline"
size="icon"
aria-label="Add default"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
</div>
<div role="group">
<button type="button" variant="outline" size="lg">Large</button>
<button type="button" variant="outline" size="lg">Button</button>
<button type="button" variant="outline" size="lg">Group</button>
<button
type="button"
variant="outline"
size="icon-lg"
aria-label="Add large"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
</div>
</section>
<fieldset orientation="vertical" aria-label="Media controls" role="group">
<button
type="button"
variant="outline"
size="icon"
aria-label="Increase"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
<hr />
<button
type="button"
variant="outline"
size="icon"
aria-label="Decrease"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14" />
</svg>
</button>
</fieldset>
<section aria-label="Button group compositions">
<div role="group">
<button
type="button"
variant="secondary"
size="sm"
ng-click="buttonGroupAction = 'Copy'"
>
Copy
</button>
<hr aria-orientation="vertical" />
<button
type="button"
variant="secondary"
size="sm"
ng-click="buttonGroupAction = 'Paste'"
>
Paste
</button>
</div>
<div role="group">
<button
type="button"
variant="secondary"
ng-click="buttonGroupAction = 'Button'"
>
Button
</button>
<hr aria-orientation="vertical" />
<button
type="button"
variant="secondary"
size="icon"
aria-label="Add item"
ng-click="buttonGroupAction = 'Add'"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
</div>
</section>
<output class="output">Action: {{ buttonGroupAction }}</output>
</main>
</body>
</html>
Composition Workflows
Button groups can connect nested groups, inputs, input groups, Select, Dropdown, and Popover triggers. Each composed component retains its own behavior and application state.
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 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="toolbarAction = 'None'; searchTerm = ''; voiceEnabled = false; currency = '$'; rtlAction = 'لا شيء'"
data-example="button-group-demo button-group-dropdown button-group-input button-group-input-group button-group-nested button-group-popover button-group-rtl button-group-select"
>
<main class="button-group-workflows">
<section
class="button-group-workflow-section button-group-menu-stage"
aria-labelledby="button-group-toolbar-heading"
>
<h2 id="button-group-toolbar-heading">Toolbar</h2>
<fieldset aria-label="Message actions" role="group">
<div role="group">
<button
type="button"
variant="outline"
size="icon"
aria-label="Go Back"
>
←
</button>
</div>
<div role="group">
<button
type="button"
variant="outline"
ng-click="toolbarAction = 'Archive'"
>
Archive
</button>
<button
type="button"
variant="outline"
ng-click="toolbarAction = 'Report'"
>
Report
</button>
</div>
<div role="group">
<button
type="button"
variant="outline"
ng-click="toolbarAction = 'Snooze'"
>
Snooze
</button>
<span ng-dropdown-menu>
<button
type="button"
variant="outline"
size="icon"
aria-label="More Options"
>
•••
</button>
<menu align="end" style="--menu-width: 10rem">
<section>
<button ng-click="toolbarAction = 'Mark as Read'">
Mark as Read
</button>
<button ng-click="toolbarAction = 'Archive'">Archive</button>
<button ng-click="toolbarAction = 'Snooze'">Snooze</button>
</section>
<span></span>
<button
variant="destructive"
ng-click="toolbarAction = 'Trash'"
>
Trash
</button>
</menu>
</span>
</div>
</fieldset>
<output class="button-group-output">
Action: {{ toolbarAction }}
</output>
</section>
<section
class="button-group-workflow-section button-group-menu-stage"
aria-labelledby="button-group-dropdown-heading"
>
<h2 id="button-group-dropdown-heading">Split dropdown</h2>
<fieldset aria-label="Follow actions" role="group">
<button type="button" variant="outline">Follow</button>
<span ng-dropdown-menu>
<button
type="button"
variant="outline"
aria-label="More follow actions"
></button>
<menu align="end" style="--menu-width: 11rem">
<section>
<button>Mute Conversation</button>
<button>Mark as Read</button>
<button>Report Conversation</button>
<button>Block User</button>
<button>Share Conversation</button>
<button>Copy Conversation</button>
</section>
<span></span>
<button variant="destructive">Delete Conversation</button>
</menu>
</span>
</fieldset>
</section>
<section
class="button-group-workflow-section"
aria-labelledby="button-group-input-heading"
>
<h2 id="button-group-input-heading">Search input</h2>
<div role="group">
<input
ng-model="searchTerm"
placeholder="Search..."
aria-label="Search query"
/>
<button
type="button"
variant="outline"
aria-label="Search"
ng-click="toolbarAction = searchTerm || 'Search'"
>
⌕
</button>
</div>
<output class="button-group-output">
Query: {{ searchTerm || 'Empty' }}
</output>
</section>
<section
class="button-group-workflow-section"
aria-labelledby="button-group-nested-heading"
>
<h2 id="button-group-nested-heading">Nested input group</h2>
<div role="group" style="--radius-md: var(--radius-full)">
<div role="group">
<button
type="button"
variant="outline"
size="icon"
aria-label="Add attachment"
>
+
</button>
</div>
<div role="group">
<div class="input-group">
<input placeholder="Send a message..." aria-label="Message" />
<span align="inline-end">⌁</span>
</div>
</div>
</div>
</section>
<section
class="button-group-workflow-section"
aria-labelledby="button-group-voice-heading"
>
<h2 id="button-group-voice-heading">Voice mode</h2>
<div role="group" style="--radius-md: var(--radius-full)">
<div role="group">
<button
type="button"
variant="outline"
size="icon"
aria-label="Add message item"
>
+
</button>
</div>
<div role="group">
<div class="input-group">
<input
placeholder="{{ voiceEnabled ? 'Record and send audio...' : 'Send a message...' }}"
ng-disabled="voiceEnabled"
aria-label="Voice message"
/>
<span align="inline-end">
<button
type="button"
size="icon-xs"
aria-label="Voice Mode"
aria-pressed="{{ voiceEnabled }}"
ng-click="voiceEnabled = !voiceEnabled"
>
⌁
</button>
</span>
</div>
</div>
</div>
</section>
<section
class="button-group-workflow-section button-group-popover-stage"
aria-labelledby="button-group-popover-heading"
>
<h2 id="button-group-popover-heading">Popover</h2>
<div role="group">
<button type="button" variant="outline">◇ Copilot</button>
<span>
<button
type="button"
variant="outline"
size="icon"
aria-label="Open Popover"
popovertarget="popover-button-group-workflows-1-content"
>
⌄
</button>
<aside
side="bottom"
aria-label="Copilot task"
class="button-group-popover-content"
id="popover-button-group-workflows-1-content"
align="center"
popover
>
<header>
<h3>Start a new task with Copilot</h3>
<p>Describe your task in natural language.</p>
</header>
<label class="visually-hidden" for="copilot-task"
>Task Description</label
>
<textarea id="copilot-task" placeholder="I need to..."></textarea>
<p class="muted">Copilot will open a pull request for review.</p>
</aside>
</span>
</div>
</section>
<section
class="button-group-workflow-section button-group-select-stage"
aria-labelledby="button-group-select-heading"
>
<h2 id="button-group-select-heading">Currency select</h2>
<div role="group">
<div role="group">
<select aria-label="Currency" ng-model="currency">
<option value="$">$ US Dollar</option>
<option value="€">€ Euro</option>
<option value="£">£ British Pound</option>
</select>
<input
placeholder="10.00"
inputmode="numeric"
aria-label="Amount"
/>
</div>
<div role="group">
<button
type="button"
variant="outline"
size="icon"
aria-label="Send"
>
→
</button>
</div>
</div>
</section>
<section
class="button-group-workflow-section button-group-menu-stage button-group-workflow-wide"
aria-labelledby="button-group-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="button-group-rtl-heading">اتجاه من اليمين إلى اليسار</h2>
<fieldset aria-label="إجراءات الرسالة" role="group">
<div role="group">
<button type="button" variant="outline">أرشفة</button>
<button type="button" variant="outline">تقرير</button>
</div>
<div role="group">
<button type="button" variant="outline">تأجيل</button>
<span ng-dropdown-menu>
<button
type="button"
variant="outline"
size="icon"
aria-label="المزيد من الخيارات"
>
•••
</button>
<menu align="end" style="--menu-width: 10rem">
<button ng-click="rtlAction = 'وضع علامة كمقروء'">
وضع علامة كمقروء
</button>
<button ng-click="rtlAction = 'أرشفة'">أرشفة</button>
<span></span>
<button
variant="destructive"
ng-click="rtlAction = 'سلة المهملات'"
>
سلة المهملات
</button>
</menu>
</span>
</div>
</fieldset>
<output class="button-group-output"> الإجراء: {{ rtlAction }} </output>
</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. Grouped native actions.
Anatomy
Root styling selector
[role="group"]
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 | Use vertical on a direct separator when it divides controls along the inline axis. |
orientation | Authored | Group layout: vertical; omit for the horizontal layout. |
role | Authored | Explicit semantic role when native HTML does not provide one. |
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
Grouped native actions. 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.
8 - card
Use article.card with optional semantic header, content, footer, and action
regions. Direct headers, headings, and header paragraphs need no part classes.
<article class="card">
<header>
<h2>Title</h2>
<p>Optional description</p>
<menu>Action</menu>
</header>
<section>Content</section>
<footer>Footer</footer>
</article>
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 Card</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="card-demo">
<article class="visual-example card">
<header>
<h2>Login to your account</h2>
<p>Enter your email below to login to your account</p>
<menu>
<button variant="link" type="button">Sign Up</button>
</menu>
</header>
<section>
<form class="card-form" id="login-form">
<div class="card-field">
<label for="card-email">Email</label>
<input
id="card-email"
type="email"
placeholder="m@example.com"
required
/>
</div>
<div class="card-field">
<div class="card-label-row">
<label for="card-password">Password</label>
<a href="#forgot-password">Forgot your password?</a>
</div>
<input id="card-password" type="password" required />
</div>
</form>
</section>
<footer class="card-footer-stacked">
<button type="submit" form="login-form">Login</button>
<button variant="outline" type="button">Login with Google</button>
</footer>
</article>
</body>
</html>
Image And RTL
Card content remains ordinary semantic HTML. Use local images, logical CSS properties, and AngularTS form or command directives for application state.
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Card 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="cardAction='No event selected'; rtl={email:'',password:'',status:'جاهز'}; smallCardAction='No report action'"
data-example="card-image card-rtl card-small"
>
<main class="card-workflows" aria-label="Card reference workflows">
<section class="card-workflow" aria-labelledby="card-image-heading">
<h2 id="card-image-heading">Image card</h2>
<article class="card-image-card card">
<div class="card-image-overlay" aria-hidden="true"></div>
<img
class="card-cover-image"
src="../../images/avatars/01.png"
alt="Abstract event cover"
/>
<header>
<menu>
<span variant="secondary" class="badge">Featured</span>
</menu>
<h2>Design systems meetup</h2>
<p>
A practical talk on component APIs, accessibility, and shipping
faster.
</p>
</header>
<footer>
<button
type="button"
class="card-full-button"
ng-click="cardAction='Viewing Design systems meetup'"
>
View Event
</button>
</footer>
</article>
<output class="card-workflow-output">{{ cardAction }}</output>
</section>
<section
class="card-workflow"
aria-labelledby="card-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="card-rtl-heading">بطاقة من اليمين إلى اليسار</h2>
<article class="card-rtl-card card" dir="rtl">
<header>
<h2>تسجيل الدخول إلى حسابك</h2>
<p>أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك</p>
<menu>
<button
variant="link"
type="button"
ng-click="rtl.status='إنشاء حساب جديد'"
>
إنشاء حساب
</button>
</menu>
</header>
<section>
<form
class="card-form"
id="rtl-login-form"
ng-submit="rtl.status='تم تسجيل الدخول باسم ' + rtl.email"
>
<div class="card-field">
<label for="card-email-rtl">البريد الإلكتروني</label>
<input
id="card-email-rtl"
type="email"
placeholder="m@example.com"
ng-model="rtl.email"
required
/>
</div>
<div class="card-field">
<div class="card-label-row">
<label for="card-password-rtl">كلمة المرور</label>
<a href="#forgot-password-rtl">نسيت كلمة المرور؟</a>
</div>
<input
id="card-password-rtl"
type="password"
ng-model="rtl.password"
required
/>
</div>
</form>
</section>
<footer class="card-footer-stacked">
<button type="submit" form="rtl-login-form">تسجيل الدخول</button>
<button
variant="outline"
type="button"
ng-click="rtl.status='متابعة باستخدام Google'"
>
تسجيل الدخول باستخدام Google
</button>
</footer>
</article>
<output class="card-workflow-output"> الحالة: {{ rtl.status }} </output>
</section>
<section class="card-workflow" aria-labelledby="card-small-heading">
<h2 id="card-small-heading">Small card</h2>
<article size="sm" class="card-small-card card">
<header>
<h2>Scheduled reports</h2>
<p>Weekly snapshots. No more manual exports.</p>
</header>
<section>
<ul class="card-feature-list">
<li>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><span>Choose a schedule (daily, or weekly).</span>
</li>
<li>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><span>Send to channels or specific teammates.</span>
</li>
<li>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><span>Include charts, tables, and key metrics.</span>
</li>
</ul>
</section>
<footer class="card-footer-stacked">
<button
size="sm"
type="button"
ng-click="smallCardAction='Scheduled reports setup'"
>
Set up scheduled reports
</button>
<button
variant="outline"
size="sm"
type="button"
ng-click="smallCardAction='Showing report updates'"
>
See what's new
</button>
</footer>
</article>
<output class="card-workflow-output">{{ smallCardAction }}</output>
</section>
</main>
</body>
</html>
Section States
Card sections are optional. CSS adapts spacing to the authored sections and
size="sm" attribute; no directive runs for a card.
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Card State 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>
<main class="component-state-grid" aria-label="Card state contracts">
<section
class="component-state-section"
aria-labelledby="complete-card-title"
>
<h2 id="complete-card-title">Complete card</h2>
<article aria-label="Complete card" class="card">
<header>
<h2>Quarterly planning</h2>
<p>Review the agenda before Monday.</p>
<menu>
<button variant="ghost" size="sm" type="button">Edit</button>
</menu>
</header>
<section>Four topics are ready for review.</section>
<footer>Updated today</footer>
</article>
</section>
<section
class="component-state-section"
aria-labelledby="minimal-card-title"
>
<h2 id="minimal-card-title">Minimal card</h2>
<article aria-label="Minimal card" class="card-minimal-state card">
No optional sections are required.
</article>
</section>
<section
class="component-state-section"
aria-labelledby="compact-card-title"
>
<h2 id="compact-card-title">Compact card</h2>
<article size="sm" aria-label="Compact card" class="card">
<header>
<h2>Storage</h2>
</header>
<footer>8.4 GB available</footer>
</article>
</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. Semantic content composition.
Anatomy
Root styling selector
.card
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 |
|---|---|---|
size | Authored | Use sm for compact spacing; omit for the default size. |
Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.
CSS custom properties
| Variable | Purpose |
|---|---|
--card-padding-block | Block padding; defaults to four spacing units, or three for size=sm. |
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
Semantic content composition. 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.
9 - chart
Use Chart to frame application-rendered HTML, SVG, canvas, or a locally bundled
chart library with a consistent container, axis, legend, and tooltip contract.
For simple authored HTML plots, data-value and data-color synchronize to
--value and --chart-color.
<figure aria-label="Monthly visitors" class="chart">
<section>
<hr />
<ul>
<li>
<span
aria-label="January desktop"
data-value="72%"
data-color="var(--chart-1)"
></span>
</li>
</ul>
</section>
<footer><span>Jan</span></footer>
</figure>
AngularCSS does not implement a chart engine. Plotting, scales, data, formatting, hover selection, and active-series state remain with authored HTML, the application’s selected chart library, and AngularTS. This keeps Chart from covering AngularTS application behavior while providing stable semantic and customization hooks.
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 Chart</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="chart-example">
<figure
class="visual-example chart"
aria-label="Desktop and mobile visitors from January through June"
>
<section>
<ul>
<li>
<span
role="img"
aria-label="January desktop"
data-value="61%"
data-color="#2563eb"
style="--value: 61%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="January mobile"
data-value="26%"
data-color="#60a5fa"
style="--value: 26%; --chart-color: #60a5fa"
></span>
</li>
<li>
<span
role="img"
aria-label="February desktop"
data-value="100%"
data-color="#2563eb"
style="--value: 100%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="February mobile"
data-value="66%"
data-color="#60a5fa"
style="--value: 66%; --chart-color: #60a5fa"
></span>
</li>
<li>
<span
role="img"
aria-label="March desktop"
data-value="78%"
data-color="#2563eb"
style="--value: 78%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="March mobile"
data-value="39%"
data-color="#60a5fa"
style="--value: 39%; --chart-color: #60a5fa"
></span>
</li>
<li>
<span
role="img"
aria-label="April desktop"
data-value="24%"
data-color="#2563eb"
style="--value: 24%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="April mobile"
data-value="62%"
data-color="#60a5fa"
style="--value: 62%; --chart-color: #60a5fa"
></span>
</li>
<li>
<span
role="img"
aria-label="May desktop"
data-value="69%"
data-color="#2563eb"
style="--value: 69%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="May mobile"
data-value="43%"
data-color="#60a5fa"
style="--value: 43%; --chart-color: #60a5fa"
></span>
</li>
<li>
<span
role="img"
aria-label="June desktop"
data-value="70%"
data-color="#2563eb"
style="--value: 70%; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="June mobile"
data-value="46%"
data-color="#60a5fa"
style="--value: 46%; --chart-color: #60a5fa"
></span>
</li>
</ul>
</section>
</figure>
</body>
</html>
Axis, grid, tooltip, and legend
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Chart 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="chartData=[{month:'January',short:'Jan',desktop:186,mobile:80,d:'61%',m:'26%'},{month:'February',short:'Feb',desktop:305,mobile:200,d:'100%',m:'66%'},{month:'March',short:'Mar',desktop:237,mobile:120,d:'78%',m:'39%'},{month:'April',short:'Apr',desktop:73,mobile:190,d:'24%',m:'62%'},{month:'May',short:'May',desktop:209,mobile:130,d:'69%',m:'43%'},{month:'June',short:'Jun',desktop:214,mobile:140,d:'70%',m:'46%'}]; tooltip={visible:false}; legendTip={visible:false}"
data-example="chart-example-grid chart-example-axis chart-example-tooltip chart-example-legend"
>
<main class="chart-workflow-grid" aria-label="Chart composition workflows">
<section class="chart-workflow" aria-labelledby="chart-grid-heading">
<h2 id="chart-grid-heading">Grid</h2>
<figure
class="chart-reference-demo chart"
aria-label="Visitor chart with horizontal grid"
>
<section>
<hr />
<ul>
<li ng-repeat="point in chartData">
<span
role="img"
aria-label="{{ point.month }} desktop"
data-value="{{ point.d }}"
data-color="#2563eb"
style="--value: {{ point.d }}; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="{{ point.month }} mobile"
data-value="{{ point.m }}"
data-color="#60a5fa"
style="--value: {{ point.m }}; --chart-color: #60a5fa"
></span>
</li>
</ul>
</section>
</figure>
</section>
<section class="chart-workflow" aria-labelledby="chart-axis-heading">
<h2 id="chart-axis-heading">Axis</h2>
<figure
class="chart-reference-demo chart"
aria-label="Visitor chart with horizontal axis"
>
<section>
<hr />
<ul>
<li ng-repeat="point in chartData">
<span
role="img"
aria-label="{{ point.month }} desktop"
data-value="{{ point.d }}"
data-color="#2563eb"
style="--value: {{ point.d }}; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="{{ point.month }} mobile"
data-value="{{ point.m }}"
data-color="#60a5fa"
style="--value: {{ point.m }}; --chart-color: #60a5fa"
></span>
</li>
</ul>
</section>
<footer>
<span ng-repeat="point in chartData"> {{ point.short }} </span>
</footer>
</figure>
</section>
<section class="chart-workflow" aria-labelledby="chart-tooltip-heading">
<h2 id="chart-tooltip-heading">Tooltip</h2>
<figure
class="chart-reference-demo chart"
aria-label="Visitor chart with tooltip"
>
<section>
<hr />
<ul>
<li
ng-repeat="point in chartData"
ng-mouseenter="tooltip.visible=true;tooltip.month=point.month;tooltip.desktop=point.desktop;tooltip.mobile=point.mobile"
ng-mouseleave="tooltip.visible=false"
>
<span
role="img"
aria-label="{{ point.month }} desktop"
data-value="{{ point.d }}"
data-color="#2563eb"
style="--value: {{ point.d }}; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="{{ point.month }} mobile"
data-value="{{ point.m }}"
data-color="#60a5fa"
style="--value: {{ point.m }}; --chart-color: #60a5fa"
></span>
</li>
</ul>
<output class="chart-floating-tooltip" ng-if="tooltip.visible">
<strong>{{ tooltip.month }}</strong>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="#2563eb"
style="--chart-color: #2563eb"
></span
>Desktop
</dt>
<dd>{{ tooltip.desktop }}</dd>
</div>
<div>
<dt>
<span
aria-hidden="true"
data-color="#60a5fa"
style="--chart-color: #60a5fa"
></span
>Mobile
</dt>
<dd>{{ tooltip.mobile }}</dd>
</div>
</dl>
</output>
</section>
<footer>
<span ng-repeat="point in chartData"> {{ point.short }} </span>
</footer>
</figure>
</section>
<section class="chart-workflow" aria-labelledby="chart-legend-heading">
<h2 id="chart-legend-heading">Legend</h2>
<figure
class="chart-reference-demo chart"
aria-label="Visitor chart with legend and tooltip"
>
<section>
<hr />
<ul>
<li
ng-repeat="point in chartData"
ng-mouseenter="legendTip.visible=true;legendTip.month=point.month;legendTip.desktop=point.desktop;legendTip.mobile=point.mobile"
ng-mouseleave="legendTip.visible=false"
>
<span
role="img"
aria-label="{{ point.month }} desktop"
data-value="{{ point.d }}"
data-color="#2563eb"
style="--value: {{ point.d }}; --chart-color: #2563eb"
></span>
<span
role="img"
aria-label="{{ point.month }} mobile"
data-value="{{ point.m }}"
data-color="#60a5fa"
style="--value: {{ point.m }}; --chart-color: #60a5fa"
></span>
</li>
</ul>
<output class="chart-floating-tooltip" ng-if="legendTip.visible">
<strong>{{ legendTip.month }}</strong>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="#2563eb"
style="--chart-color: #2563eb"
></span
>Desktop
</dt>
<dd>{{ legendTip.desktop }}</dd>
</div>
<div>
<dt>
<span
aria-hidden="true"
data-color="#60a5fa"
style="--chart-color: #60a5fa"
></span
>Mobile
</dt>
<dd>{{ legendTip.mobile }}</dd>
</div>
</dl>
</output>
</section>
<footer>
<span ng-repeat="point in chartData"> {{ point.short }} </span>
</footer>
<ul>
<li>
<span data-color="#2563eb" style="--chart-color: #2563eb"></span
>Desktop
</li>
<li>
<span data-color="#60a5fa" style="--chart-color: #60a5fa"></span
>Mobile
</li>
</ul>
</figure>
</section>
</main>
</body>
</html>
Interactive, RTL, and tooltip variants
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Chart 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="activeChart='desktop'; demoTip={visible:false}; rtlTip={visible:false}; interactiveData=[{date:'Apr 1',d:222,m:150,dp:'49%',mp:'36%'},{date:'Apr 2',d:97,m:180,dp:'21%',mp:'43%'},{date:'Apr 3',d:167,m:120,dp:'37%',mp:'29%'},{date:'Apr 4',d:242,m:260,dp:'53%',mp:'62%'},{date:'Apr 5',d:373,m:290,dp:'82%',mp:'69%'},{date:'Apr 6',d:301,m:340,dp:'66%',mp:'81%'},{date:'Apr 7',d:245,m:180,dp:'54%',mp:'43%'},{date:'Apr 8',d:409,m:320,dp:'90%',mp:'76%'},{date:'Apr 9',d:59,m:110,dp:'13%',mp:'26%'},{date:'Apr 10',d:261,m:190,dp:'57%',mp:'45%'},{date:'Apr 11',d:327,m:350,dp:'72%',mp:'83%'},{date:'Apr 12',d:292,m:210,dp:'64%',mp:'50%'},{date:'Apr 13',d:342,m:380,dp:'75%',mp:'90%'},{date:'Apr 14',d:137,m:220,dp:'30%',mp:'52%'},{date:'Apr 15',d:120,m:170,dp:'26%',mp:'40%'},{date:'Apr 16',d:138,m:190,dp:'30%',mp:'45%'},{date:'Apr 17',d:446,m:360,dp:'98%',mp:'86%'},{date:'Apr 18',d:364,m:410,dp:'80%',mp:'98%'},{date:'Apr 19',d:243,m:180,dp:'54%',mp:'43%'},{date:'Apr 20',d:89,m:150,dp:'20%',mp:'36%'},{date:'Apr 21',d:137,m:200,dp:'30%',mp:'48%'},{date:'Apr 22',d:224,m:170,dp:'49%',mp:'40%'},{date:'Apr 23',d:138,m:230,dp:'30%',mp:'55%'},{date:'Apr 24',d:387,m:290,dp:'85%',mp:'69%'},{date:'Apr 25',d:215,m:250,dp:'47%',mp:'60%'},{date:'Apr 26',d:75,m:130,dp:'17%',mp:'31%'},{date:'Apr 27',d:383,m:420,dp:'84%',mp:'100%'},{date:'Apr 28',d:122,m:180,dp:'27%',mp:'43%'},{date:'Apr 29',d:315,m:240,dp:'69%',mp:'57%'},{date:'Apr 30',d:454,m:380,dp:'100%',mp:'90%'}]; rtlData=[{month:'يناير',short:'ينا',desktop:186,mobile:80,d:'61%',m:'26%'},{month:'فبراير',short:'فبر',desktop:305,mobile:200,d:'100%',m:'66%'},{month:'مارس',short:'مار',desktop:237,mobile:120,d:'78%',m:'39%'},{month:'أبريل',short:'أبر',desktop:73,mobile:190,d:'24%',m:'62%'},{month:'مايو',short:'ماي',desktop:209,mobile:130,d:'69%',m:'43%'},{month:'يونيو',short:'يون',desktop:214,mobile:140,d:'70%',m:'46%'}]"
data-example="chart-demo chart-rtl chart-tooltip"
>
<main
class="chart-composition-grid"
aria-label="Chart reference compositions"
>
<article class="chart-interactive-card chart-composition-wide card">
<header class="chart-interactive-header">
<div class="chart-interactive-copy">
<h2>Bar Chart - Interactive</h2>
<p>Showing total visitors for the last 3 months</p>
</div>
<div class="chart-series-controls" aria-label="Visitor series">
<button
type="button"
variant="ghost"
aria-pressed="{{ activeChart == 'desktop' }}"
ng-click="activeChart='desktop'"
>
<span>Desktop</span><strong>7,324</strong>
</button>
<button
type="button"
variant="ghost"
aria-pressed="{{ activeChart == 'mobile' }}"
ng-click="activeChart='mobile'"
>
<span>Mobile</span><strong>7,250</strong>
</button>
</div>
</header>
<section class="chart-interactive-content">
<figure
class="chart-interactive-demo chart"
aria-label="Interactive daily visitors"
>
<section>
<hr />
<div class="chart-daily-bars">
<span
role="img"
ng-repeat="point in interactiveData"
aria-label="{{ point.date }} {{ activeChart }}"
data-value="{{ activeChart == 'desktop' ? point.dp : point.mp }}"
data-color="{{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
ng-mouseenter="demoTip.visible=true;demoTip.date=point.date;demoTip.value=activeChart == 'desktop' ? point.d : point.m"
ng-mouseleave="demoTip.visible=false"
style="--value: {{ activeChart == 'desktop' ? point.dp : point.mp }}; --chart-color: {{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
></span>
</div>
<output class="chart-floating-tooltip" ng-if="demoTip.visible">
<strong>{{ demoTip.date }}, 2024</strong>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="{{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
style="--chart-color: {{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
></span>
{{ activeChart == 'desktop' ? 'Desktop' : 'Mobile' }}
</dt>
<dd>{{ demoTip.value }}</dd>
</div>
</dl>
</output>
</section>
<footer class="chart-date-axis">
<span>Apr 1</span>
<span>Apr 8</span>
<span>Apr 15</span>
<span>Apr 22</span>
<span>Apr 30</span>
</footer>
</figure>
</section>
</article>
<section
class="chart-composition"
aria-labelledby="chart-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="chart-rtl-heading">مخطط من اليمين إلى اليسار</h2>
<figure
class="chart-reference-demo chart"
aria-label="زوار سطح المكتب والجوال"
>
<section>
<hr />
<ul>
<li
ng-repeat="point in rtlData"
ng-mouseenter="rtlTip.visible=true;rtlTip.month=point.month;rtlTip.desktop=point.desktop;rtlTip.mobile=point.mobile"
ng-mouseleave="rtlTip.visible=false"
>
<span
role="img"
aria-label="{{ point.month }} سطح المكتب"
data-value="{{ point.d }}"
data-color="var(--chart-2)"
style="--value: {{ point.d }}; --chart-color: var(--chart-2)"
></span>
<span
role="img"
aria-label="{{ point.month }} الجوال"
data-value="{{ point.m }}"
data-color="var(--chart-1)"
style="--value: {{ point.m }}; --chart-color: var(--chart-1)"
></span>
</li>
</ul>
<output class="chart-floating-tooltip" ng-if="rtlTip.visible">
<strong>{{ rtlTip.month }}</strong>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="var(--chart-2)"
style="--chart-color: var(--chart-2)"
></span
>سطح المكتب
</dt>
<dd>{{ rtlTip.desktop }}</dd>
</div>
<div>
<dt>
<span
aria-hidden="true"
data-color="var(--chart-1)"
style="--chart-color: var(--chart-1)"
></span
>الجوال
</dt>
<dd>{{ rtlTip.mobile }}</dd>
</div>
</dl>
</output>
</section>
<footer>
<span ng-repeat="point in rtlData"> {{ point.short }} </span>
</footer>
<ul>
<li>
<span
data-color="var(--chart-2)"
style="--chart-color: var(--chart-2)"
></span
>سطح المكتب
</li>
<li>
<span
data-color="var(--chart-1)"
style="--chart-color: var(--chart-1)"
></span
>الجوال
</li>
</ul>
</figure>
</section>
<section
class="chart-composition"
aria-labelledby="chart-tooltip-gallery-heading"
>
<h2 id="chart-tooltip-gallery-heading">Tooltip anatomy</h2>
<figure
class="chart-tooltip-gallery chart"
aria-label="Chart tooltip anatomy examples"
>
<output>
<strong>Page Views</strong>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="var(--chart-1)"
style="--chart-color: var(--chart-1)"
></span
>Desktop
</dt>
<dd>186</dd>
</div>
<div>
<dt>
<span
aria-hidden="true"
data-color="var(--chart-2)"
style="--chart-color: var(--chart-2)"
></span
>Mobile
</dt>
<dd>80</dd>
</div>
</dl>
</output>
<output>
<dl>
<div>
<dt>
<span
aria-hidden="true"
indicator="dashed"
data-color="var(--chart-3)"
style="--chart-color: var(--chart-3)"
></span
>Chrome
</dt>
<dd>1,286</dd>
</div>
<div>
<dt>
<span
aria-hidden="true"
indicator="dashed"
data-color="var(--chart-4)"
style="--chart-color: var(--chart-4)"
></span
>Firefox
</dt>
<dd>1,000</dd>
</div>
</dl>
</output>
<output>
<dl>
<div>
<dt>
<span
aria-hidden="true"
indicator="line"
data-color="var(--chart-3)"
style="--chart-color: var(--chart-3)"
></span
><strong>Page Views</strong><br />Desktop
</dt>
<dd>12,486</dd>
</div>
</dl>
</output>
<output>
<dl>
<div>
<dt>
<span
aria-hidden="true"
data-color="var(--chart-1)"
style="--chart-color: var(--chart-1)"
></span
>Chrome
</dt>
<dd>1,286</dd>
</div>
</dl>
</output>
</figure>
</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. Authored figures, tables, and CSS variables.
Anatomy
Root styling selector
.chart
Semantic structure
Apply .chart to an accessible figure. Compose its optional title, plot, grid, grouped bars, axis, legend, and tooltip from semantic header, section, hr, ul, li, footer, output, and description-list elements; no anatomy classes are required.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
data-color | Authored | Series color key used by the example or application to set --chart-color. |
data-value | Authored | Authored bar height as a percentage when --value is not set. |
indicator | Authored | Legend indicator: line or dashed; omit for a solid mark. |
Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.
CSS custom properties
| Variable | Purpose |
|---|---|
--chart-color | Color for an authored series, mark, or legend indicator. |
--value | Bar height as a percentage; falls back to data-value and then 50%. |
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
Semantic figure, heading, list, and data markup owns chart meaning. CSS variables provide visual values and colors; authored HTML, SVG, canvas, or an application-selected chart library owns plotting, scales, data, formatting, and interaction. AngularCSS registers no chart directive.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Give every chart root a useful accessible name and provide a textual or tabular equivalent when exact values matter. Bars expose authored labels and values; axes and legends are lists; grid decoration is hidden; visible tooltips are status regions. Never use color as the only distinction between series.
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 - description-list
Use a native description list for stable record labels and values. AngularCSS adds responsive row presentation without changing the relationship between terms and descriptions.
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 Description List</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="description-list-demo">
<dl class="visual-example" aria-label="Account details">
<div>
<dt>Account owner</dt>
<dd>Ada Lovelace</dd>
</div>
<div>
<dt>Email</dt>
<dd>ada@example.com</dd>
</div>
<div>
<dt>Plan</dt>
<dd>Enterprise</dd>
</div>
<div>
<dt>Last updated</dt>
<dd><time datetime="2026-09-05">5 September 2026</time></dd>
</div>
</dl>
</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 description-list structure for record details.
Anatomy
Root styling selector
dl:has(> div > dt):has(> div > dd)
Semantic structure
Use a native dl and wrap each related dt and dd group in a direct div so rows adapt without any component or part classes.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
orientation | Authored | Row layout: horizontal or vertical; omit to become vertical on narrow viewports. |
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
Description List styles native terms and descriptions for record details. The application owns values, formatting, redaction, and conditional rendering.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use native dl, dt, and dd elements. Group each term and its descriptions in a div when row styling is needed, and keep sensitive values subject to application authorization.
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 - disclosure
Native details and summary own click, keyboard, focus, and disclosure state.
AngularCSS only styles the authored structure. AngularTS may observe native
events when the application needs the state.
<details class="disclosure">
<summary>Order details</summary>
<div>Shipping address and item details.</div>
</details>
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 Disclosure</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="disclosure-demo">
<details class="disclosure visual-example">
<summary>
<header>
<h2>Order #4189</h2>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m7 15 5 5 5-5M7 9l5-5 5 5" />
</svg>
<span class="visually-hidden">Toggle details</span>
</header>
<p><span>Status</span><strong>Shipped</strong></p>
</summary>
<section>
<article>
<p><strong>Shipping address</strong></p>
<p>100 Market St, San Francisco</p>
</article>
<article>
<p><strong>Items</strong></p>
<p>2x Studio Headphones</p>
</article>
</section>
</details>
</body>
</html>
Basic, settings, 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 Disclosure 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="disclosure-basic disclosure-rtl disclosure-settings"
>
<main class="disclosure-workflow-grid" aria-label="Disclosure workflows">
<section
class="disclosure-workflow"
aria-labelledby="disclosure-basic-heading"
>
<h2 id="disclosure-basic-heading">Basic</h2>
<div class="disclosure-basic-card card">
<section>
<details class="disclosure disclosure-product">
<summary>
<span>Product details</span>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m6 9 6 6 6-6" />
</svg>
</summary>
<div>
<p>
This panel can be expanded or collapsed to reveal additional
content.
</p>
<button size="xs">Learn More</button>
</div>
</details>
</section>
</div>
</section>
<section
class="disclosure-workflow"
aria-labelledby="disclosure-settings-heading"
>
<h2 id="disclosure-settings-heading">Settings</h2>
<div size="sm" class="disclosure-settings-card card">
<header>
<h2>Radius</h2>
<p>Set the corner radius of the element.</p>
</header>
<section>
<section class="disclosure-settings">
<div class="disclosure-settings-fields">
<label class="visually-hidden" for="radius-x">Radius X</label>
<input id="radius-x" type="number" value="0" />
<label class="visually-hidden" for="radius-y">Radius Y</label>
<input id="radius-y" type="number" value="0" />
<details class="disclosure disclosure-settings-disclosure">
<summary aria-label="Toggle additional radius settings">
<svg
class="disclosure-maximize"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path
d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3m8 0h3a2 2 0 0 0 2-2v-3"
/>
</svg>
<svg
class="disclosure-minimize"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path
d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3m8 0v-3a2 2 0 0 1 2-2h3"
/>
</svg>
</summary>
<div class="disclosure-settings-more">
<label class="visually-hidden" for="radius-bottom-x"
>Bottom radius X</label
>
<input id="radius-bottom-x" type="number" value="0" />
<label class="visually-hidden" for="radius-bottom-y"
>Bottom radius Y</label
>
<input id="radius-bottom-y" type="number" value="0" />
</div>
</details>
</div>
</section>
</section>
</div>
</section>
<section
class="disclosure-workflow disclosure-workflow-wide"
aria-labelledby="disclosure-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="disclosure-rtl-heading">من اليمين إلى اليسار</h2>
<details class="disclosure">
<summary>
<header>
<h4>الطلب #4189</h4>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="m7 15 5 5 5-5M7 9l5-5 5 5" />
</svg>
<span class="visually-hidden">تبديل التفاصيل</span>
</header>
<p><span>الحالة</span><strong>تم الشحن</strong></p>
</summary>
<section>
<article>
<p><strong>عنوان الشحن</strong></p>
<p>100 Market St, San Francisco</p>
</article>
<article>
<p><strong>العناصر</strong></p>
<p>2x سماعات الاستوديو</p>
</article>
</section>
</details>
</section>
</main>
</body>
</html>
File tree
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Disclosure 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 data-example="disclosure-file-tree">
<main aria-label="Disclosure file tree composition">
<div size="sm" class="disclosure-file-card visual-example card">
<header>
<section ng-tabs>
<menu aria-label="File views">
<button aria-selected="true">Explorer</button>
<button>Outline</button>
</menu>
<section>
<span class="visually-hidden">Explorer file tree</span>
</section>
<section>
<span class="visually-hidden">No outline available</span>
</section>
</section>
</header>
<section>
<div class="disclosure-file-tree">
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>components</span>
</summary>
<div>
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>ui</span>
</summary>
<div>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>button.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>card.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>dialog.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>input.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>select.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>table.tsx
</button>
</div>
</details>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>login-form.tsx
</button>
<button variant="link" size="sm">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
/>
<path d="M14 2v6h6" /></svg
>register-form.tsx
</button>
</div>
</details>
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>lib</span>
</summary>
<div>
<button variant="link" size="sm">utils.ts</button
><button variant="link" size="sm">cn.ts</button
><button variant="link" size="sm">api.ts</button>
</div>
</details>
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>hooks</span>
</summary>
<div>
<button variant="link" size="sm">use-media-query.ts</button
><button variant="link" size="sm">use-debounce.ts</button
><button variant="link" size="sm">use-local-storage.ts</button>
</div>
</details>
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>types</span>
</summary>
<div>
<button variant="link" size="sm">index.d.ts</button
><button variant="link" size="sm">api.d.ts</button>
</div>
</details>
<details class="disclosure">
<summary>
<svg
class="tree-chevron"
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
>
<path d="m9 18 6-6-6-6" /></svg
><svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4 19V5a2 2 0 0 1 2-2h5l2 3h5a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"
/></svg
><span>public</span>
</summary>
<div>
<button variant="link" size="sm">favicon.ico</button
><button variant="link" size="sm">logo.svg</button
><button variant="link" size="sm">images</button>
</div>
</details>
<button variant="link" size="sm">app.tsx</button>
<button variant="link" size="sm">layout.tsx</button>
<button variant="link" size="sm">globals.css</button>
<button variant="link" size="sm">package.json</button>
<button variant="link" size="sm">tsconfig.json</button>
<button variant="link" size="sm">README.md</button>
<button variant="link" size="sm">.gitignore</button>
</div>
</section>
</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 details and summary disclosure.
Anatomy
Root styling selector
.disclosure
Semantic structure
Apply .disclosure to a native details element with a direct summary followed by authored content. No nested AngularCSS attributes are required.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
open | Authored | Initial or controlled open 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 details and summary own disclosure, focus, and keyboard behavior. Use open for initial state and AngularTS only when application state must observe or control the native element. AngularCSS registers no disclosure directive.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use a direct summary as the accessible trigger. The browser exposes disclosure state and provides Enter and Space activation without authored roles or ARIA state.
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 - empty
Empty states compose media, title, description, and action content parts.
<section class="empty">
<header>
<figure variant="icon"></figure>
<h2>No projects yet</h2>
<p>Create your first project.</p>
</header>
</section>
Example
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Empty</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="empty-demo">
<section class="visual-example empty" aria-live="polite">
<header>
<figure variant="icon">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.75"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 9.75h16.5m-13.5 0V6.75A2.25 2.25 0 0 1 9 4.5h6a2.25 2.25 0 0 1 2.25 2.25v3m-12 0 1.2 8.4A2.25 2.25 0 0 0 8.68 20.25h6.64a2.25 2.25 0 0 0 2.23-2.1l1.2-8.4"
/>
</svg>
</figure>
<h2>No Projects Yet</h2>
<p>
You haven't created any projects yet. Get started by creating your
first project.
</p>
</header>
<section>
<div class="row">
<button>Create Project</button>
<button variant="outline">Import Project</button>
</div>
</section>
<a class="empty-learn-more" href="#learn-more">
Learn More
<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>
</a>
</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 Empty 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="emptyQuery='';emptyAction='Ready'"
>
<main class="empty-workflow-grid" aria-label="Empty state workflows">
<section data-example="empty-avatar" class="empty-workflow empty">
<header>
<figure>
<span class="empty-avatar-large avatar"
><img src="../../images/avatars/01.png" alt="Jane Doe" /><span
>JD</span
></span
>
</figure>
<h2>User Offline</h2>
<p>
This user is currently offline. Leave a message or try again later.
</p>
</header>
<section>
<button
size="sm"
type="button"
ng-click="emptyAction='Message queued'"
>
Leave Message
</button>
</section>
</section>
<section data-example="empty-avatar-group" class="empty-workflow empty">
<header>
<figure class="empty-avatar-group">
<span class="avatar"
><img src="../../images/avatars/01.png" alt="Jane" /></span
><span class="avatar"
><img src="../../images/avatars/02.png" alt="Alex" /></span
><span class="avatar"
><img src="../../images/avatars/03.png" alt="Sam"
/></span>
</figure>
<h2>No Team Members</h2>
<p>Invite your team to collaborate on this project.</p>
</header>
<section>
<button
size="sm"
type="button"
ng-click="emptyAction='Invite opened'"
>
+ Invite Members
</button>
</section>
</section>
<section
data-example="empty-background"
class="empty-workflow empty-muted-demo empty"
>
<header>
<figure variant="icon">!</figure>
<h2>No Notifications</h2>
<p>You're all caught up. New notifications will appear here.</p>
</header>
<section>
<button
variant="outline"
type="button"
ng-click="emptyAction='Refreshed'"
>
Refresh
</button>
</section>
</section>
<section
data-example="empty-card"
class="empty-workflow empty-card-demo empty"
>
<header>
<figure variant="icon">□</figure>
<h2>No projects yet</h2>
<p>
You haven't created any projects yet. Create your first project.
</p>
</header>
<section>
<div class="row">
<button type="button" ng-click="emptyAction='Create project'">
Create project</button
><button
variant="outline"
type="button"
ng-click="emptyAction='Import project'"
>
Import project
</button>
</div>
<a href="#learn">Learn more</a>
</section>
</section>
<section data-example="empty-input-group" class="empty-workflow empty">
<header>
<h2>404 - Not Found</h2>
<p>The page you're looking for doesn't exist. Try searching below.</p>
</header>
<section>
<div class="input-group">
<input
ng-model="emptyQuery"
placeholder="Try searching for pages..."
aria-label="Search missing pages"
/>
<div>⌕</div>
<div align="inline-end">
<kbd>/</kbd>
</div>
</div>
<p>Need help? <a href="#support">Contact support</a></p>
</section>
</section>
<section
data-example="empty-outline"
class="empty-workflow empty-outline-demo empty"
>
<header>
<figure variant="icon">☁</figure>
<h2>Cloud Storage Empty</h2>
<p>Upload files to access them anywhere.</p>
</header>
<section>
<button
variant="outline"
size="sm"
type="button"
ng-click="emptyAction='Upload opened'"
>
Upload Files
</button>
</section>
</section>
<section
data-example="empty-rtl"
class="empty-workflow empty"
dir="rtl"
lang="ar"
>
<header>
<figure variant="icon">□</figure>
<h2>لا توجد مشاريع بعد</h2>
<p>لم تقم بإنشاء أي مشاريع بعد. ابدأ بإنشاء مشروعك الأول.</p>
</header>
<section>
<div class="row">
<button type="button" ng-click="emptyAction='إنشاء مشروع'">
إنشاء مشروع</button
><button
variant="outline"
type="button"
ng-click="emptyAction='استيراد مشروع'"
>
استيراد مشروع
</button>
</div>
</section>
</section>
<output class="empty-workflow-output">
{{ emptyAction }} · {{ emptyQuery }}
</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. Semantic empty-state content.
Anatomy
Root styling selector
.empty
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 |
|---|---|---|
variant | Authored | Optional direct figure presentation: icon; omit for the default media treatment. |
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
Semantic empty-state content. 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 - field
Use the field wrapper and field parts to define standard form structure.
<div class="field">
<label for="email">Email</label>
<input id="email" type="email" placeholder="Email" />
<p>Use your work email.</p>
</div>
<div class="field">
<label for="invalid-email">Email</label>
<input id="invalid-email" aria-invalid="true" />
<p class="field-error">Enter a valid email.</p>
</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 Field</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="name='Jane Doe'; email=''">
<form class="stack">
<fieldset class="field-set">
<legend>Profile</legend>
<div class="field-group">
<div class="field">
<label for="demo-profile-name">Name</label>
<input
id="demo-profile-name"
aria-describedby="demo-profile-name-description"
placeholder="Jane Doe"
ng-model="name"
/>
<p id="demo-profile-name-description">
Use your public display name.
</p>
</div>
<div class="field">
<label for="demo-profile-email"> Email </label>
<input
id="demo-profile-email"
type="email"
placeholder="Enter an email"
required
aria-describedby="demo-profile-email-error"
ng-model="email"
/>
<p
id="demo-profile-email-error"
ng-show="!email"
class="field-error"
>
Enter a valid email.
</p>
</div>
</div>
</fieldset>
<output class="output">
Preview: <span ng-bind="name"></span>
<span ng-bind="email ? '(' + email + ')' : '(email required)'"></span>
</output>
</form>
</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 Field 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="fieldState={username:'',password:'',feedback:'',department:'',hardDisks:true,externalDisks:false,cds:false,servers:false,sync:true,twoFactor:false,plan:'monthly',environment:'kubernetes',minimum:200,maximum:800,street:'',city:'',zip:'',push:true,pushTasks:false,emailTasks:false,profileName:'',message:'Ready',sameAsShipping:true,month:'',year:''}"
>
<main class="field-workflow-grid" aria-label="Field workflows">
<section data-example="field-input" class="field-workflow">
<fieldset class="field-set">
<div class="field-group">
<div class="field">
<label for="field-username">Username</label
><input
id="field-username"
ng-model="fieldState.username"
placeholder="Max Leiter"
/>
<p>Choose a unique username for your account.</p>
</div>
<div class="field">
<label for="field-password">Password</label>
<p>Must be at least 8 characters long.</p>
<input
id="field-password"
type="password"
ng-model="fieldState.password"
placeholder="••••••••"
/>
</div>
</div>
</fieldset>
</section>
<section data-example="field-textarea" class="field-workflow">
<fieldset class="field-set">
<div class="field-group">
<div class="field">
<label for="field-feedback">Feedback</label
><textarea
id="field-feedback"
ng-model="fieldState.feedback"
placeholder="Your feedback helps us improve..."
rows="4"
></textarea>
<p>Share your thoughts about our service.</p>
</div>
</div>
</fieldset>
</section>
<section data-example="field-select" class="field-workflow">
<div class="field">
<label for="field-department">Department</label>
<select id="field-department" ng-model="fieldState.department">
<option value="">Choose department</option>
<option>Engineering</option>
<option>Design</option>
<option>Marketing</option>
<option>Sales</option>
<option>Customer Support</option>
</select>
<p>Select your department or area of work.</p>
</div>
</section>
<section data-example="field-checkbox" class="field-workflow">
<div class="field-group">
<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="field-choice-list checkbox-group">
<div orientation="horizontal" class="field">
<input
id="field-hard-disks"
type="checkbox"
ng-model="fieldState.hardDisks"
/><label for="field-hard-disks">Hard disks</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-external-disks"
type="checkbox"
ng-model="fieldState.externalDisks"
/><label for="field-external-disks">External disks</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-cds"
type="checkbox"
ng-model="fieldState.cds"
/><label for="field-cds">CDs, DVDs, and iPods</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-servers"
type="checkbox"
ng-model="fieldState.servers"
/><label for="field-servers">Connected servers</label>
</div>
</div>
</fieldset>
<hr />
<div orientation="horizontal" class="field">
<input id="field-sync" type="checkbox" ng-model="fieldState.sync" />
<section>
<label for="field-sync"
>Sync Desktop & Documents folders</label
>
<p>Access these folders from your other devices.</p>
</section>
</div>
</div>
</section>
<section data-example="field-switch" class="field-workflow">
<div orientation="horizontal" class="field-switch-demo field">
<label for="field-2fa">Multi-factor authentication</label
><input
role="switch"
id="field-2fa"
type="checkbox"
ng-model="fieldState.twoFactor"
/>
</div>
</section>
<section data-example="field-radio" class="field-workflow">
<fieldset class="field-set field-choice-list">
<legend variant="label">Subscription Plan</legend>
<p>Yearly and lifetime plans offer significant savings.</p>
<div orientation="horizontal" class="field">
<input
id="field-monthly"
name="field-plan"
type="radio"
value="monthly"
ng-model="fieldState.plan"
/><label for="field-monthly">Monthly ($9.99/month)</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-yearly"
name="field-plan"
type="radio"
value="yearly"
ng-model="fieldState.plan"
/><label for="field-yearly">Yearly ($99.99/year)</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-lifetime"
name="field-plan"
type="radio"
value="lifetime"
ng-model="fieldState.plan"
/><label for="field-lifetime">Lifetime ($299.99)</label>
</div>
</fieldset>
</section>
<section data-example="field-slider" class="field-workflow">
<div class="field">
<strong>Price Range</strong>
<p>
Set your budget range (${{ fieldState.minimum }} - ${{
fieldState.maximum }}).
</p>
<div
ng-range-slider
min="0"
max="1000"
aria-label="Price Range"
class="field-slider-demo"
>
<input
type="range"
min="0"
max="1000"
step="10"
ng-model="fieldState.minimum"
aria-label="Minimum budget"
/><input
type="range"
min="0"
max="1000"
step="10"
ng-model="fieldState.maximum"
aria-label="Maximum budget"
/>
</div>
</div>
</section>
<section data-example="field-choice-card" class="field-workflow">
<div class="field-group">
<fieldset class="field-set field-card-list">
<legend variant="label">Compute Environment</legend>
<p>Select the compute environment for your cluster.</p>
<label for="field-kubernetes"
><div orientation="horizontal" class="field">
<section>
<strong>Kubernetes</strong>
<p>Run GPU workloads on a K8s cluster.</p>
</section>
<input
id="field-kubernetes"
name="environment"
type="radio"
value="kubernetes"
ng-model="fieldState.environment"
/></div></label
><label for="field-vm"
><div orientation="horizontal" class="field">
<section>
<strong>Virtual Machine</strong>
<p>Access a cluster to run GPU workloads.</p>
</section>
<input
id="field-vm"
name="environment"
type="radio"
value="vm"
ng-model="fieldState.environment"
/></div
></label>
</fieldset>
</div>
</section>
<section data-example="field-fieldset" class="field-workflow">
<fieldset class="field-set">
<legend>Address Information</legend>
<p>We need your address to deliver your order.</p>
<div class="field-group">
<div class="field">
<label for="field-street">Street Address</label
><input
id="field-street"
ng-model="fieldState.street"
placeholder="123 Main St"
/>
</div>
<div class="field-two-column">
<div class="field">
<label for="field-city">City</label
><input
id="field-city"
ng-model="fieldState.city"
placeholder="New York"
/>
</div>
<div class="field">
<label for="field-zip">Postal Code</label
><input
id="field-zip"
ng-model="fieldState.zip"
placeholder="90502"
/>
</div>
</div>
</div>
</fieldset>
</section>
<section data-example="field-group" class="field-workflow">
<div class="field-group">
<fieldset class="field-set">
<label>Responses</label>
<p>
Get notified when ChatGPT responds to requests that take time.
</p>
<div orientation="horizontal" class="field">
<input
id="field-push"
type="checkbox"
ng-model="fieldState.push"
disabled
/><label for="field-push">Push notifications</label>
</div>
</fieldset>
<hr />
<fieldset class="field-set">
<label>Tasks</label>
<p>
Get notified when tasks have updates.
<a href="#tasks">Manage tasks</a>
</p>
<div class="field-choice-list">
<div orientation="horizontal" class="field">
<input
id="field-push-tasks"
type="checkbox"
ng-model="fieldState.pushTasks"
/><label for="field-push-tasks">Push notifications</label>
</div>
<div orientation="horizontal" class="field">
<input
id="field-email-tasks"
type="checkbox"
ng-model="fieldState.emailTasks"
/><label for="field-email-tasks">Email notifications</label>
</div>
</div>
</fieldset>
</div>
</section>
<section
data-example="field-responsive"
class="field-workflow field-workflow-wide"
>
<form
ng-submit="fieldState.message='Profile submitted '+fieldState.profileName"
>
<fieldset class="field-set">
<legend>Profile</legend>
<p>Fill in your profile information.</p>
<div class="field-group">
<div orientation="responsive" class="field">
<section>
<label for="field-profile-name">Name</label>
<p>Provide your full name for identification</p>
</section>
<input
id="field-profile-name"
ng-model="fieldState.profileName"
placeholder="Evil Rabbit"
required
/>
</div>
<div orientation="responsive" class="field-form-actions field">
<button type="submit">Submit</button
><button
type="button"
variant="outline"
ng-click="fieldState.message='Cancelled'"
>
Cancel
</button>
</div>
</div>
</fieldset>
</form>
</section>
<section
data-example="field-demo"
class="field-workflow field-workflow-wide"
>
<form ng-submit="fieldState.message='Payment submitted'">
<div class="field-group">
<fieldset class="field-set">
<legend>Payment Method</legend>
<p>All transactions are secure and encrypted</p>
<div class="field-group">
<div class="field">
<label for="field-card-name">Name on Card</label
><input
id="field-card-name"
placeholder="Evil Rabbit"
required
/>
</div>
<div class="field">
<label for="field-card-number">Card Number</label
><input
id="field-card-number"
placeholder="1234 5678 9012 3456"
required
/>
<p>Enter your 16-digit card number</p>
</div>
<div class="field-three-column">
<div class="field">
<label for="field-month">Month</label
><input id="field-month" placeholder="MM" />
</div>
<div class="field">
<label for="field-year">Year</label
><input id="field-year" placeholder="YYYY" />
</div>
<div class="field">
<label for="field-cvv">CVV</label
><input id="field-cvv" placeholder="123" required />
</div>
</div>
</div>
</fieldset>
<hr />
<fieldset class="field-set">
<legend>Billing Address</legend>
<p>The billing address associated with your payment method</p>
<div orientation="horizontal" class="field">
<input
id="field-same-shipping"
type="checkbox"
ng-model="fieldState.sameAsShipping"
/><label for="field-same-shipping"
>Same as shipping address</label
>
</div>
</fieldset>
<fieldset class="field-set">
<div class="field">
<label for="field-comments">Comments</label
><textarea
id="field-comments"
placeholder="Add any additional comments"
></textarea>
</div>
</fieldset>
<div orientation="horizontal" class="field-form-actions field">
<button type="submit">Submit</button
><button type="button" variant="outline">Cancel</button>
</div>
</div>
</form>
</section>
<section
data-example="field-rtl"
class="field-workflow field-workflow-wide"
dir="rtl"
lang="ar"
>
<form>
<div class="field-group">
<fieldset class="field-set">
<legend>طريقة الدفع</legend>
<p>جميع المعاملات آمنة ومشفرة</p>
<div class="field-group">
<div class="field">
<label for="field-card-name-rtl">الاسم على البطاقة</label
><input id="field-card-name-rtl" placeholder="Evil Rabbit" />
</div>
<div class="field">
<label for="field-card-number-rtl">رقم البطاقة</label
><input
id="field-card-number-rtl"
placeholder="1234 5678 9012 3456"
/>
<p>أدخل رقم البطاقة المكون من 16 رقمًا</p>
</div>
<div class="field-three-column">
<div class="field">
<label>الشهر</label><input placeholder="ش.ش" />
</div>
<div class="field">
<label>السنة</label><input placeholder="YYYY" />
</div>
<div class="field">
<label>CVV</label><input placeholder="123" />
</div>
</div>
</div>
</fieldset>
<hr />
<div orientation="horizontal" class="field">
<input
id="field-same-shipping-rtl"
type="checkbox"
checked
/><label for="field-same-shipping-rtl">نفس عنوان الشحن</label>
</div>
<div class="field">
<label for="field-comments-rtl">تعليقات</label
><textarea
id="field-comments-rtl"
placeholder="أضف أي تعليقات إضافية"
></textarea>
</div>
<div orientation="horizontal" class="field-form-actions field">
<button type="button">إرسال</button
><button type="button" variant="outline">إلغاء</button>
</div>
</div>
</form>
</section>
<output class="field-workflow-output"> {{ fieldState.message }} </output>
</main>
</body>
</html>
Validation States
Fields derive presentation from native validity and aria-invalid; AngularTS
structural directives may insert or remove controls and descriptions.
View source
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AngularCSS Field State 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="state={requiredEmail:'',dynamicVisible:false}"
>
<form class="component-state-grid" aria-label="Field state contracts">
<section
class="component-state-section"
aria-labelledby="field-messages-title"
>
<h2 id="field-messages-title">Messages</h2>
<div id="message-field" class="field">
<label for="message-control">Name</label>
<input
id="message-control"
aria-describedby="message-description message-error"
/>
<p id="message-description">Use your public display name.</p>
<p id="message-error" class="field-error">
The display name is already in use.
</p>
</div>
</section>
<section
class="component-state-section"
aria-labelledby="field-invalid-title"
>
<h2 id="field-invalid-title">Invalid state</h2>
<div id="explicit-invalid-field" class="field">
<label for="explicit-invalid-control"> Workspace </label>
<input id="explicit-invalid-control" aria-invalid="true" />
</div>
</section>
<section
class="component-state-section"
aria-labelledby="field-required-title"
>
<h2 id="field-required-title">Native validation</h2>
<div id="required-field" class="field">
<label for="required-email">Email</label>
<input
id="required-email"
type="email"
required
ng-model="state.requiredEmail"
/>
</div>
</section>
<section
class="component-state-section"
aria-labelledby="field-dynamic-title"
>
<h2 id="field-dynamic-title">Conditional control</h2>
<div id="dynamic-field" class="field">
<label for="dynamic-email">Team email</label>
<p id="dynamic-email-description">Use the address for your team.</p>
<input
ng-if="state.dynamicVisible"
id="dynamic-email"
type="email"
aria-describedby="dynamic-email-description"
required
/>
</div>
<button
variant="outline"
type="button"
ng-click="state.dynamicVisible=true"
ng-disabled="state.dynamicVisible"
>
Add email field
</button>
</section>
</form>
</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 labels, descriptions, and validation.
Anatomy
Root styling selector
.field
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. |
orientation | Authored | Field layout: horizontal or responsive; omit for the vertical layout. |
variant | Authored | Compact label typography when authored on a fieldset legend. |
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
Field is a styling-only semantic form composition. Native labels, validation, and aria-describedby own relationships; AngularTS forms and structural directives own model, error visibility, and submission state.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Connect every control to a native label. Give descriptions and errors stable IDs and author aria-describedby on the control. Use native fieldset and legend only for actual groups of related 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.
14 - file-upload
Keep file selection native and present application-owned queue and progress state beside it. AngularTS can handle drop events and backend transfer commands without introducing a second upload 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 File Upload</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="file-upload-demo">
<section class="visual-example" aria-labelledby="upload-title">
<header>
<h2 id="upload-title">Supporting documents</h2>
<p>PDF, PNG, or JPG files up to 10 MB.</p>
</header>
<label for="supporting-files">
<strong>Choose files or drop them here</strong>
<span>The application validates and transfers selected files.</span>
<input
id="supporting-files"
type="file"
accept=".pdf,image/png,image/jpeg"
multiple
/>
</label>
<ul aria-label="Upload queue">
<li>
<span>contract.pdf</span>
<output>72%</output>
<progress value="72" max="100">72%</progress>
</li>
</ul>
<output aria-live="polite">1 file ready for processing</output>
</section>
</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 file input and authored status.
Anatomy
Root styling selector
section:has(> label > input[type="file"])
Semantic structure
Use a semantic section with a direct label containing a native file input. Optional direct ul, native progress, and output elements present application-owned queue and transfer state without component or part classes.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
accept | Authored | Native accepted file types on the direct file input. |
dragging | Authored | Presentational drop-target state on the root section. |
multiple | Authored | Allows the direct native file input to accept several files. |
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
File Upload styles a native file input, authored queue, native progress, and status output. AngularTS or the application owns drag-and-drop event handling, validation, transfer, retry, cancellation, and persistence.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Keep the native file input operable and labeled. Announce queue changes with a status output, label progress, and expose validation or transfer errors as text rather than color alone.
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 - filter-bar
Use a native form to collect a data view’s search and filter values. Submit, reset, AngularTS binding, and backend queries keep their existing ownership.
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 Filter Bar</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="filter-bar-demo">
<main class="visual-example">
<form role="search" aria-label="Filter orders">
<fieldset>
<legend class="visually-hidden">Order filters</legend>
<label>
Search
<input type="search" name="query" placeholder="Order or customer" />
</label>
<label>
Status
<select name="status">
<option value="">All statuses</option>
<option>Open</option>
<option>Complete</option>
</select>
</label>
</fieldset>
<menu>
<button variant="outline" type="reset">Reset</button>
<button type="submit">Apply</button>
</menu>
</form>
</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. Semantic search and filter form.
Anatomy
Root styling selector
form[role="search"]:has(> fieldset + menu)
Semantic structure
Use role="search" on a native form with a direct fieldset followed by a direct action menu. Put labeled controls in the fieldset and submit or reset actions in the menu.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
role | Authored | Explicit semantic role when native HTML does not provide one. |
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
Filter Bar is a native form composition. The browser and AngularTS own control values and submission; the backend may remain authoritative for queries, result counts, and pagination.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use a native form and fieldset with accessible labels. Submit applies the query, reset restores defaults, and result changes should be announced near the results they affect.
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.
16 - input-group
Use .input-group with one native control and optional authored addons, text,
and buttons. AngularTS continues to own the model and actions.
<div class="input-group">
<input id="search" placeholder="Search" />
<label for="search" align="inline-start">Search</label>
<div align="inline-end">⌘K</div>
</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 Input 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>
<main class="stack">
<div class="field">
<label for="search">Search</label>
<div class="input-group">
<input id="search" placeholder="Search documentation..." />
<label for="search" align="inline-start">
<span aria-hidden="true">⌕</span>
</label>
</div>
</div>
</main>
</body>
</html>
Reference Workflows
These packaged examples cover default, disabled, invalid, inline, text, icon, keyboard-hint, label, Button Group, and Card 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 Input 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="query=''; message=''; copyStatus='Ready'; cardStatus=''; username='angularcss'"
data-example="input-group-workflows"
>
<svg class="example-icon-definitions" aria-hidden="true">
<defs>
<symbol id="ig-search" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.3-4.3"></path>
</symbol>
<symbol id="ig-mail" viewBox="0 0 24 24">
<rect width="20" height="16" x="2" y="4" rx="2"></rect>
<path d="m22 7-10 6L2 7"></path>
</symbol>
<symbol id="ig-card" viewBox="0 0 24 24">
<rect width="20" height="14" x="2" y="5" rx="2"></rect>
<path d="M2 10h20"></path>
</symbol>
<symbol id="ig-check" viewBox="0 0 24 24">
<path d="m5 12 4 4L19 6"></path>
</symbol>
<symbol id="ig-eye-off" viewBox="0 0 24 24">
<path d="m2 2 20 20"></path>
<path
d="M6.7 6.7C4.8 8 3.3 9.8 2.5 12c1.5 4 5.2 7 9.5 7 1.5 0 2.9-.3 4.1-.9"
></path>
<path
d="M10.7 5.1A10 10 0 0 1 12 5c4.3 0 8 3 9.5 7a10.8 10.8 0 0 1-2.1 3.4"
></path>
</symbol>
<symbol id="ig-star" viewBox="0 0 24 24">
<path
d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8-6.2-3.2L5.8 21 7 14.2 2 9.3l6.9-1Z"
></path>
</symbol>
<symbol id="ig-info" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4M12 8h.01"></path>
</symbol>
<symbol id="ig-link" viewBox="0 0 24 24">
<path
d="M10 13a5 5 0 0 0 7.1.1l2-2a5 5 0 0 0-7.1-7.1l-1.1 1.1"
></path>
<path d="M14 11a5 5 0 0 0-7.1-.1l-2 2A5 5 0 0 0 12 20l1.1-1.1"></path>
</symbol>
</defs>
</svg>
<main class="input-group-workflow-grid" aria-label="Input group examples">
<section
class="input-group-workflow"
data-example="input-group-basic"
aria-labelledby="input-group-basic-title"
>
<h2 id="input-group-basic-title">States</h2>
<div class="field-group">
<div class="field">
<label for="ig-default">Default</label>
<input id="ig-default" placeholder="Placeholder" />
</div>
<div class="field">
<label for="ig-basic">Input group</label>
<div class="input-group">
<input id="ig-basic" placeholder="Placeholder" />
</div>
</div>
<div class="field">
<label for="ig-disabled">Disabled</label>
<div class="input-group">
<input
id="ig-disabled"
placeholder="This field is disabled"
disabled
/>
</div>
</div>
<div class="field">
<label for="ig-invalid">Invalid</label>
<div class="input-group">
<input
id="ig-invalid"
placeholder="This field is invalid"
aria-invalid="true"
/>
</div>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-demo input-group-inline-start input-group-inline-end input-group-kbd"
aria-labelledby="input-group-position-title"
>
<h2 id="input-group-position-title">Inline addons</h2>
<div class="input-group">
<input
ng-model="query"
placeholder="Search..."
aria-label="Search documentation"
/>
<div align="inline-start">
<svg aria-hidden="true"><use href="#ig-search"></use></svg>
</div>
<div align="inline-end">{{ query ? '12 results' : 'No query' }}</div>
</div>
<div class="input-group">
<input
type="password"
placeholder="Enter password"
aria-label="Password"
/>
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-eye-off"></use></svg>
</div>
</div>
<div class="input-group">
<input id="ig-command-search" placeholder="Search commands..." />
<label for="ig-command-search">
<svg aria-hidden="true"><use href="#ig-search"></use></svg>
</label>
<div align="inline-end">
<kbd>⌘K</kbd>
</div>
</div>
<output class="input-group-output">
Query: {{ query || 'none' }}
</output>
</section>
<section
class="input-group-workflow"
data-example="input-group-icon"
aria-labelledby="input-group-icon-title"
>
<h2 id="input-group-icon-title">Icons</h2>
<div class="input-group">
<input
type="email"
placeholder="Enter your email"
aria-label="Email with icon"
/>
<div>
<svg aria-hidden="true"><use href="#ig-mail"></use></svg>
</div>
</div>
<div class="input-group">
<input placeholder="Card number" aria-label="Verified card number" />
<div>
<svg aria-hidden="true"><use href="#ig-card"></use></svg>
</div>
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-check"></use></svg>
</div>
</div>
<div class="input-group">
<input placeholder="Favorite card" aria-label="Favorite card" />
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-star"></use></svg>
<svg aria-hidden="true"><use href="#ig-info"></use></svg>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-text"
aria-labelledby="input-group-text-title"
>
<h2 id="input-group-text-title">Text addons</h2>
<div class="input-group">
<div>
<span>$</span>
</div>
<input inputmode="decimal" placeholder="0.00" aria-label="Amount" />
<div align="inline-end">
<span>USD</span>
</div>
</div>
<div class="input-group">
<div>
<span>https://</span>
</div>
<input placeholder="example.com" aria-label="Website" />
<div align="inline-end">
<span>.com</span>
</div>
</div>
<div class="input-group">
<input
placeholder="Enter your username"
aria-label="Company username"
/>
<div align="inline-end">
<span>@company.com</span>
</div>
</div>
</section>
<section
class="input-group-workflow input-group-workflow-wide"
data-example="input-group-with-addons"
aria-labelledby="input-group-addons-title"
>
<h2 id="input-group-addons-title">Addon positions</h2>
<div class="input-group-pair-grid">
<div class="field">
<label for="ig-addon-start">Inline start and end</label>
<div class="input-group">
<input id="ig-addon-start" />
<div>
<svg aria-hidden="true"><use href="#ig-search"></use></svg>
</div>
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-info"></use></svg>
</div>
</div>
</div>
<div class="field">
<label for="ig-addon-header">Block start</label>
<div class="input-group">
<input id="ig-addon-header" />
<div align="block-start">
<span>First name</span>
<svg class="input-group-push-end" aria-hidden="true">
<use href="#ig-info"></use>
</svg>
</div>
</div>
</div>
<div class="field">
<label for="ig-addon-footer">Block end</label>
<div class="input-group">
<input id="ig-addon-footer" />
<div align="block-end">
<span>20/240 characters</span>
<svg class="input-group-push-end" aria-hidden="true">
<use href="#ig-info"></use>
</svg>
</div>
</div>
</div>
<div class="field">
<label for="ig-addon-optional">Label and optional text</label>
<div class="input-group">
<div>
<label for="ig-addon-optional">Label</label>
</div>
<input id="ig-addon-optional" />
<div align="inline-end">
<span>(optional)</span>
</div>
</div>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-with-kbd"
aria-labelledby="input-group-kbd-title"
>
<h2 id="input-group-kbd-title">Keyboard hints</h2>
<div class="input-group">
<input placeholder="Search for apps..." aria-label="Search apps" />
<div align="inline-end">Ask AI</div>
<div align="inline-end">
<kbd>Tab</kbd>
</div>
</div>
<div class="input-group">
<input ng-model="username" aria-label="Username" />
<div align="inline-end">
<span class="input-group-valid-icon"
><svg aria-hidden="true"><use href="#ig-check"></use></svg
></span>
</div>
</div>
<p class="input-group-success">This username is available.</p>
<div class="input-group">
<input value="angularcss" aria-label="Loading username" disabled />
<div align="inline-end">
<output size="sm" aria-label="Loading" class="spinner"></output>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-label"
aria-labelledby="input-group-label-title"
>
<h2 id="input-group-label-title">Labels in addons</h2>
<div class="input-group">
<input id="ig-email-name" placeholder="angularcss" />
<div>
<label for="ig-email-name">@</label>
</div>
</div>
<div class="input-group">
<input id="ig-email-address" placeholder="team@angularcss.dev" />
<div align="block-start">
<label for="ig-email-address">Email</label>
<span ng-tooltip class="input-group-push-end">
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Email help"
>
<svg aria-hidden="true"><use href="#ig-info"></use></svg>
</button>
<span side="top">We'll use this to send notifications.</span>
</span>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-button-group"
aria-labelledby="input-group-button-group-title"
>
<h2 id="input-group-button-group-title">Button group</h2>
<div role="group">
<label for="ig-url">https://</label>
<div class="input-group">
<input id="ig-url" aria-label="URL" />
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-link"></use></svg>
</div>
</div>
<span>.com</span>
</div>
</section>
<section
class="input-group-workflow input-group-card-workflow"
data-example="input-group-in-card"
aria-labelledby="input-group-card-title"
>
<article class="card">
<header>
<h2 id="input-group-card-title">Card with input group</h2>
<p>Collect contact details and feedback.</p>
</header>
<section>
<div class="field-group">
<div class="field">
<label for="ig-card-email">Email address</label>
<div class="input-group">
<input
id="ig-card-email"
type="email"
placeholder="you@example.com"
/>
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-mail"></use></svg>
</div>
</div>
</div>
<div class="field">
<label for="ig-card-site">Website URL</label>
<div class="input-group">
<div>
<span>https://</span>
</div>
<input id="ig-card-site" placeholder="example.com" />
<div align="inline-end">
<svg aria-hidden="true"><use href="#ig-link"></use></svg>
</div>
</div>
</div>
</div>
</section>
<footer class="input-group-card-actions">
<button
variant="outline"
type="button"
ng-click="cardStatus='Cancelled'"
>
Cancel
</button>
<button type="button" ng-click="cardStatus='Submitted'">
Submit
</button>
<output class="input-group-output">{{ cardStatus }}</output>
</footer>
</article>
</section>
</main>
</body>
</html>
Interactive Compositions
Buttons, dropdown menus, tooltips, popovers, calling-code selection, and mixed Button Group compositions run from AngularTS bindings in the built artifact.
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 Group 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="copied=false; favorite=false; country='+1'; compositionStatus='Ready'"
data-example="input-group-compositions"
>
<svg class="example-icon-definitions" aria-hidden="true">
<defs>
<symbol id="igc-copy" viewBox="0 0 24 24">
<rect width="14" height="14" x="8" y="8" rx="2"></rect>
<path
d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
></path>
</symbol>
<symbol id="igc-check" viewBox="0 0 24 24">
<path d="m5 12 4 4L19 6"></path>
</symbol>
<symbol id="igc-star" viewBox="0 0 24 24">
<path
d="m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8-6.2-3.2L5.8 21 7 14.2 2 9.3l6.9-1Z"
></path>
</symbol>
<symbol id="igc-info" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4M12 8h.01"></path>
</symbol>
<symbol id="igc-help" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"></circle>
<path d="M9.1 9a3 3 0 1 1 5.8 1c0 2-3 2-3 4M12 18h.01"></path>
</symbol>
<symbol id="igc-more" viewBox="0 0 24 24">
<circle cx="5" cy="12" r="1"></circle>
<circle cx="12" cy="12" r="1"></circle>
<circle cx="19" cy="12" r="1"></circle>
</symbol>
<symbol id="igc-chevron" viewBox="0 0 24 24">
<path d="m6 9 6 6 6-6"></path>
</symbol>
<symbol id="igc-trash" viewBox="0 0 24 24">
<path d="M3 6h18M8 6V4h8v2M19 6l-1 16H6L5 6M10 11v6M14 11v6"></path>
</symbol>
</defs>
</svg>
<main
class="input-group-composition-grid"
aria-label="Interactive input group compositions"
>
<section
class="input-group-workflow"
data-example="input-group-button"
aria-labelledby="igc-button-title"
>
<h2 id="igc-button-title">Buttons</h2>
<div class="input-group">
<input
value="https://x.com/angularcss"
aria-label="Share URL"
readonly
/>
<div align="inline-end">
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Copy URL"
ng-click="copied=true; compositionStatus='Copied URL'"
>
<svg aria-hidden="true">
<use ng-if="!copied" href="#igc-copy"></use>
<use ng-if="copied" href="#igc-check"></use>
</svg>
</button>
</div>
</div>
<div class="input-group-pill input-group">
<span>
<button
size="icon-xs"
variant="secondary"
type="button"
aria-label="Connection information"
popovertarget="popover-input-group-compositions-1-content"
>
<svg aria-hidden="true"><use href="#igc-info"></use></svg>
</button>
<aside
class="input-group-popover-content"
aria-label="Connection status"
id="popover-input-group-compositions-1-content"
side="bottom"
align="start"
popover
>
<strong>Your connection is not secure.</strong>
<p>You should not enter sensitive information on this site.</p>
</aside>
</span>
<div>https://</div>
<input aria-label="Secure URL" />
<div align="inline-end">
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Favorite URL"
aria-pressed="{{ favorite }}"
ng-click="favorite=!favorite; compositionStatus=favorite ? 'Added favorite' : 'Removed favorite'"
>
<svg aria-hidden="true">
<use href="#igc-star"></use>
</svg>
</button>
</div>
</div>
<div class="input-group">
<input placeholder="Type to search..." aria-label="Search query" />
<div align="inline-end">
<button
variant="secondary"
type="button"
ng-click="compositionStatus='Search submitted'"
>
Search
</button>
</div>
</div>
<output class="input-group-output">{{ compositionStatus }}</output>
</section>
<section
class="input-group-workflow"
data-example="input-group-with-buttons"
aria-labelledby="igc-variants-title"
>
<h2 id="igc-variants-title">Button variants</h2>
<div class="input-group">
<input aria-label="Default action" />
<div>
<button type="button" ng-click="compositionStatus='Default action'">
Default
</button>
</div>
</div>
<div class="input-group">
<input aria-label="Outline action" />
<div>
<button
variant="outline"
type="button"
ng-click="compositionStatus='Outline action'"
>
Outline
</button>
</div>
</div>
<div class="input-group">
<input aria-label="Secondary action" />
<div align="inline-end">
<button
variant="secondary"
type="button"
ng-click="compositionStatus='Secondary action'"
>
Button
</button>
</div>
</div>
<div class="input-group">
<input aria-label="Delete action" />
<div align="inline-end">
<button
size="icon-xs"
variant="secondary"
type="button"
aria-label="Delete"
ng-click="compositionStatus='Deleted'"
>
<svg aria-hidden="true"><use href="#igc-trash"></use></svg>
</button>
</div>
</div>
</section>
<section
class="input-group-workflow input-group-menu-workflow"
data-example="input-group-dropdown"
aria-labelledby="igc-dropdown-title"
>
<h2 id="igc-dropdown-title">Dropdown menus</h2>
<div class="input-group">
<input placeholder="Enter file name" aria-label="File name" />
<div align="inline-end">
<span ng-dropdown-menu class="input-group-overlay-control">
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="File options"
>
<svg aria-hidden="true"><use href="#igc-more"></use></svg>
</button>
<menu align="end" style="--menu-width: 10rem">
<button ng-click="compositionStatus='Settings'">
Settings
</button>
<button ng-click="compositionStatus='Copied path'">
Copy path
</button>
<button ng-click="compositionStatus='Opened location'">
Open location
</button>
</menu>
</span>
</div>
</div>
<div class="input-group">
<input
placeholder="Enter search query"
aria-label="Search query with scope"
/>
<div align="inline-end">
<span ng-dropdown-menu class="input-group-overlay-control">
<button variant="ghost" type="button">
Search in
<svg aria-hidden="true"><use href="#igc-chevron"></use></svg>
</button>
<menu align="end" style="--menu-width: 10rem">
<button ng-click="compositionStatus='Documentation'">
Documentation
</button>
<button ng-click="compositionStatus='Blog posts'">
Blog posts
</button>
<button ng-click="compositionStatus='Changelog'">
Changelog
</button>
</menu>
</span>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-tooltip"
aria-labelledby="igc-tooltip-title"
>
<h2 id="igc-tooltip-title">Tooltips</h2>
<div class="input-group">
<input
type="password"
placeholder="Enter password"
aria-label="Password requirements"
/>
<div align="inline-end">
<span ng-tooltip>
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Password information"
>
<svg aria-hidden="true"><use href="#igc-info"></use></svg>
</button>
<span side="top">Password must be at least 8 characters.</span>
</span>
</div>
</div>
<div class="input-group">
<input
placeholder="Your email address"
aria-label="Notification email"
/>
<div align="inline-end">
<span ng-tooltip>
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Email help"
>
<svg aria-hidden="true"><use href="#igc-help"></use></svg>
</button>
<span side="top">We'll use this to send notifications.</span>
</span>
</div>
</div>
<div class="input-group">
<input placeholder="Enter API key" aria-label="API key" />
<div align="inline-end">
<span ng-tooltip>
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="API key help"
>
<svg aria-hidden="true"><use href="#igc-help"></use></svg>
</button>
<span side="left">Click for help with API keys.</span>
</span>
</div>
</div>
</section>
<section
class="input-group-workflow input-group-workflow-wide"
data-example="input-group-with-tooltip"
aria-labelledby="igc-mixed-title"
>
<h2 id="igc-mixed-title">Mixed interactive controls</h2>
<div class="input-group-pair-grid">
<div class="field">
<label for="igc-tooltip-input">Tooltip</label>
<div class="input-group">
<input id="igc-tooltip-input" />
<div align="inline-end">
<span ng-tooltip
><button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Input information"
>
<svg aria-hidden="true">
<use href="#igc-info"></use>
</svg></button
><span side="top">This is content in a tooltip.</span></span
>
</div>
</div>
<p>This is a description of the input group.</p>
</div>
<div class="field">
<label for="igc-country-input">Dropdown</label>
<div class="input-group">
<input id="igc-country-input" type="tel" />
<div>
<span ng-dropdown-menu class="input-group-overlay-control">
<button variant="ghost" type="button">
{{ country }}
<svg aria-hidden="true">
<use href="#igc-chevron"></use>
</svg>
</button>
<menu align="end" style="--menu-width: 5rem">
<button ng-click="country='+1'">+1</button>
<button ng-click="country='+44'">+44</button>
<button ng-click="country='+46'">+46</button>
</menu>
</span>
</div>
</div>
<p>Select a calling code.</p>
</div>
<div class="field">
<label for="igc-popover-input">Popover</label>
<div class="input-group">
<span>
<button
size="icon-xs"
variant="secondary"
type="button"
aria-label="Security details"
popovertarget="popover-input-group-compositions-2-content"
>
<svg aria-hidden="true"><use href="#igc-info"></use></svg>
</button>
<aside
class="input-group-popover-content"
aria-label="Security details"
id="popover-input-group-compositions-2-content"
side="bottom"
align="start"
popover
>
<strong>Your connection is not secure.</strong>
<p>Do not enter sensitive information on this site.</p>
</aside>
</span>
<div>https://</div>
<input id="igc-popover-input" />
<div align="inline-end">
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Add favorite"
ng-click="compositionStatus='Added to favorites'"
>
<svg aria-hidden="true"><use href="#igc-star"></use></svg>
</button>
</div>
</div>
</div>
<div class="field">
<label for="igc-group-url">Button group</label>
<div role="group">
<span>https://</span>
<div class="input-group">
<input id="igc-group-url" />
<div align="inline-end">
<svg aria-hidden="true"><use href="#igc-info"></use></svg>
</div>
</div>
<span>.com</span>
</div>
</div>
</div>
</section>
</main>
</body>
</html>
Textarea And Block Addons
Block-start and block-end addons, textarea states, a code editor, character counters, and the autosizing custom control remain native form controls.
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 Group Textarea 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="comment=''; commentCount=0; code=''; codeColumn=1; customText=''; customCount=0; textareaStatus='Ready'"
data-example="input-group-textarea-workflows"
>
<svg class="example-icon-definitions" aria-hidden="true">
<defs>
<symbol id="igt-copy" viewBox="0 0 24 24">
<rect width="14" height="14" x="8" y="8" rx="2"></rect>
<path
d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
></path>
</symbol>
<symbol id="igt-refresh" viewBox="0 0 24 24">
<path d="M20 11a8 8 0 1 0 2 5M20 4v7h-7"></path>
</symbol>
<symbol id="igt-code-icon" viewBox="0 0 24 24">
<path d="m16 18 6-6-6-6M8 6l-6 6 6 6M14.5 4l-5 16"></path>
</symbol>
<symbol id="igt-send" viewBox="0 0 24 24">
<path d="m22 2-7 20-4-9-9-4ZM22 2 11 13"></path>
</symbol>
<symbol id="igt-info" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4M12 8h.01"></path>
</symbol>
</defs>
</svg>
<main
class="input-group-textarea-grid"
aria-label="Input group textarea examples"
>
<section
class="input-group-workflow"
data-example="input-group-block-start"
aria-labelledby="igt-start-title"
>
<h2 id="igt-start-title">Block start</h2>
<div class="field">
<label for="igt-start-input">Input</label>
<div class="input-group">
<input id="igt-start-input" placeholder="Enter your name" />
<div align="block-start">
<span>Full name</span>
</div>
</div>
<p>Header positioned above the input.</p>
</div>
<div class="field">
<label for="igt-start-textarea">Textarea</label>
<div class="input-group">
<textarea
id="igt-start-textarea"
placeholder="console.log('Hello, world!');"
></textarea>
<div align="block-start" border="true">
<svg aria-hidden="true"><use href="#igt-code-icon"></use></svg>
<span class="input-group-mono">script.js</span>
<button
size="icon-xs"
class="input-group-push-end"
variant="ghost"
type="button"
aria-label="Copy code"
ng-click="textareaStatus='Copied code'"
>
<svg aria-hidden="true"><use href="#igt-copy"></use></svg>
</button>
</div>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-block-end"
aria-labelledby="igt-end-title"
>
<h2 id="igt-end-title">Block end</h2>
<div class="field">
<label for="igt-amount">Input</label>
<div class="input-group">
<input
id="igt-amount"
inputmode="decimal"
placeholder="Enter amount"
/>
<div align="block-end">
<span>USD</span>
</div>
</div>
<p>Footer positioned below the input.</p>
</div>
<div class="field">
<label for="igt-comment">Textarea</label>
<div class="input-group">
<textarea
id="igt-comment"
ng-model="comment"
data-change="commentCount=comment.length"
maxlength="280"
placeholder="Write a comment..."
></textarea>
<div align="block-end">
<span>{{ commentCount }}/280</span>
<button
size="sm"
class="input-group-push-end"
type="button"
ng-click="textareaStatus='Posted comment'"
>
Post
</button>
</div>
</div>
<p>Footer positioned below the textarea.</p>
</div>
</section>
<section
class="input-group-workflow input-group-workflow-wide"
data-example="input-group-textarea"
aria-labelledby="igt-editor-title"
>
<h2 id="igt-editor-title">Code editor</h2>
<div class="input-group-code-editor input-group">
<textarea
id="igt-code"
ng-model="code"
data-change="codeColumn=code.length+1"
placeholder="console.log('Hello, world!');"
aria-label="JavaScript code"
></textarea>
<div align="block-start" border="true">
<span class="input-group-mono"
><svg aria-hidden="true"><use href="#igt-code-icon"></use></svg
>script.js</span
>
<button
size="icon-xs"
class="input-group-push-end"
variant="ghost"
type="button"
aria-label="Refresh code"
ng-click="code=''; textareaStatus='Reset code'"
>
<svg aria-hidden="true"><use href="#igt-refresh"></use></svg>
</button>
<button
size="icon-xs"
variant="ghost"
type="button"
aria-label="Copy code"
ng-click="textareaStatus='Copied code'"
>
<svg aria-hidden="true"><use href="#igt-copy"></use></svg>
</button>
</div>
<div align="block-end" border="true">
<span>Line 1, Column {{ codeColumn }}</span>
<button
size="sm"
class="input-group-push-end"
type="button"
ng-click="textareaStatus='Ran code'"
>
Run
</button>
</div>
</div>
<output class="input-group-output">{{ textareaStatus }}</output>
</section>
<section
class="input-group-workflow input-group-workflow-wide"
data-example="input-group-textarea-examples"
aria-labelledby="igt-examples-title"
>
<h2 id="igt-examples-title">Textarea states and addons</h2>
<div class="input-group-pair-grid">
<div class="field">
<label for="igt-default-textarea">Default textarea</label>
<textarea
id="igt-default-textarea"
placeholder="Enter your text here..."
></textarea>
</div>
<div class="field">
<label for="igt-invalid-textarea">Invalid</label>
<div class="input-group">
<textarea
id="igt-invalid-textarea"
aria-invalid="true"
placeholder="Enter your text here..."
></textarea>
</div>
</div>
<div class="field">
<label for="igt-disabled-textarea">Disabled</label>
<div class="input-group">
<textarea
id="igt-disabled-textarea"
disabled
placeholder="Enter your text here..."
></textarea>
</div>
</div>
<div class="field">
<label for="igt-prompt">Addon (block start)</label>
<div class="input-group">
<textarea id="igt-prompt"></textarea>
<div align="block-start">
<span>Ask, search or chat...</span
><svg class="input-group-push-end" aria-hidden="true">
<use href="#igt-info"></use>
</svg>
</div>
</div>
</div>
<div class="field">
<label for="igt-send-comment">Addon (send)</label>
<div class="input-group">
<textarea
id="igt-send-comment"
ng-model="comment"
data-change="commentCount=comment.length"
placeholder="Enter your text here..."
></textarea>
<div align="block-end">
<span>{{ commentCount }}/280 characters</span
><button
size="icon-xs"
class="input-group-push-end input-group-round-button"
type="button"
aria-label="Send"
ng-click="textareaStatus='Sent message'"
>
<svg aria-hidden="true"><use href="#igt-send"></use></svg>
</button>
</div>
</div>
</div>
<div class="field">
<label for="igt-actions">Addon (buttons)</label>
<div class="input-group">
<textarea
id="igt-actions"
placeholder="Share your thoughts..."
></textarea>
<div align="block-end">
<button
size="sm"
class="input-group-push-end"
variant="ghost"
type="button"
ng-click="textareaStatus='Cancelled comment'"
>
Cancel</button
><button
size="sm"
type="button"
ng-click="textareaStatus='Posted comment'"
>
Post comment
</button>
</div>
</div>
</div>
</div>
</section>
<section
class="input-group-workflow"
data-example="input-group-custom"
aria-labelledby="igt-custom-title"
>
<h2 id="igt-custom-title">Autosizing custom control</h2>
<div class="input-group">
<textarea
class="input-group-autosize"
ng-model="customText"
data-change="customCount=customText.length"
placeholder="Autoresize textarea..."
aria-label="Autosize textarea"
></textarea>
<div align="block-end">
<span>{{ customCount }} characters</span
><button
size="sm"
class="input-group-push-end"
type="button"
ng-click="textareaStatus='Submitted custom text'"
>
Submit
</button>
</div>
</div>
</section>
</main>
</body>
</html>
Right To Left
Logical addon placement and AngularTS model updates work without RTL-specific component markup.
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 Input Group 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="rtlQuery=''; rtlComment=''; rtlCount=0; rtlStatus='جاهز'"
data-example="input-group-rtl"
>
<main
class="input-group-rtl-workflow"
aria-label="مجموعات إدخال من اليمين إلى اليسار"
>
<div class="input-group">
<input ng-model="rtlQuery" placeholder="بحث..." aria-label="بحث" />
<div align="inline-start">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.3-4.3"></path>
</svg>
</div>
<div align="inline-end">١٢ نتيجة</div>
</div>
<div class="input-group">
<input placeholder="جاري البحث..." aria-label="جاري البحث" />
<div align="inline-end">
<output size="sm" aria-label="تحميل" class="spinner"></output>
</div>
</div>
<div class="input-group">
<input placeholder="جاري حفظ التغييرات..." aria-label="جاري الحفظ" />
<div align="inline-end">
<span>جاري الحفظ...</span
><output size="sm" aria-label="تحميل" class="spinner"></output>
</div>
</div>
<div class="field">
<label for="input-group-rtl-comment">منطقة النص</label>
<div class="input-group">
<textarea
id="input-group-rtl-comment"
ng-model="rtlComment"
data-change="rtlCount=rtlComment.length"
maxlength="280"
placeholder="اكتب تعليقًا..."
></textarea>
<div align="block-end">
<span>{{ rtlCount }}/٢٨٠</span>
<button
size="sm"
class="input-group-push-end"
type="button"
ng-click="rtlStatus='تم النشر'"
>
نشر
</button>
</div>
</div>
<p>تذييل موضع أسفل منطقة النص.</p>
</div>
<output class="input-group-output">
{{ rtlStatus }} · {{ rtlQuery || 'لا يوجد بحث' }}
</output>
</main>
</body>
</html>
Addon States
Visible addons participate in the control description. AngularCSS preserves external description IDs as AngularTS inserts or hides addon content.
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 Group State 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="query='AngularCSS'; showCurrency=false; priceHidden=false"
>
<main class="component-state-grid" aria-label="Input group state contracts">
<section
class="component-state-section"
aria-labelledby="described-group-title"
>
<h2 id="described-group-title">Described addons</h2>
<p id="external-help" class="component-state-help">
Enter an invoice total.
</p>
<div id="described-group" class="input-group">
<input
aria-label="Invoice total"
aria-describedby="external-help currency-code"
/>
<span id="currency-code">USD</span>
<span align="inline-end" aria-hidden="true"> .00 </span>
</div>
</section>
<section
class="component-state-section"
aria-labelledby="button-group-title"
>
<h2 id="button-group-title">Action button</h2>
<div id="button-group" class="input-group">
<input aria-label="Documentation search" ng-model="query" />
<button type="button" ng-click="query=''">Clear</button>
</div>
</section>
<section
class="component-state-section"
aria-labelledby="dynamic-group-title"
>
<h2 id="dynamic-group-title">Conditional addon</h2>
<div id="dynamic-group" class="input-group">
<input
ng-attr-aria-label="{{ showCurrency ? 'Budget in USD' : 'Budget' }}"
aria-describedby="budget-help"
/>
<span ng-if="showCurrency" id="dynamic-addon"> USD </span>
</div>
<p id="budget-help" class="component-state-help">Monthly budget</p>
<button
variant="outline"
type="button"
ng-click="showCurrency=true"
ng-disabled="showCurrency"
>
Add currency
</button>
</section>
<section
class="component-state-section"
aria-labelledby="hidden-group-title"
>
<h2 id="hidden-group-title">Hidden addon</h2>
<div id="hidden-group" class="input-group">
<input aria-label="Price" aria-describedby="price-help" />
<span id="addon-price" ng-attr-aria-hidden="{{ priceHidden }}">
USD
</span>
</div>
<p id="price-help" class="component-state-help">Price before tax</p>
<button
variant="outline"
type="button"
ng-click="priceHidden=!priceHidden"
>
Toggle currency description
</button>
</section>
</main>
</body>
</html>
Clicking a non-button addon focuses the grouped control. Interactive addon content remains responsible for its own native or composed behavior.
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. Grouped native controls and addons.
Anatomy
Root styling selector
.input-group
Semantic structure
Use one native input, textarea, select, combobox, or spinbutton inside .input-group. Addons may be placed at inline-start, inline-end, block-start, or block-end with align. Buttons, menus, tooltips, and popovers retain their own behavior.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
align | Authored | Direct addon placement: inline-start, inline-end, block-start, or block-end. |
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
border | Authored | Use true on a direct block addon to draw its dividing border. |
size | Authored | Direct action size: sm, icon-xs, or icon-sm; omit for the compact addon action. |
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 Group is styling-only. Native controls own focus, values, validation, and submission. Use a native label addon when clicking addon text should focus the control; AngularTS owns dynamic text and actions.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Keep one clearly labeled native control in each group. Use aria-describedby for explanatory addon text, aria-hidden for decorative text, and a native label for when an addon should focus the control.
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.
17 - input-otp
Use one native input. The browser owns editing, paste, autofill, and validation.
<label for="code">One-time code</label>
<input
id="code"
autocomplete="one-time-code"
inputmode="numeric"
pattern="[0-9]{6}"
maxlength="6"
ng-model="code"
/>
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 Otp</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="otp='123456'"
data-example="input-otp-demo"
>
<div class="stack-sm">
<label for="one-time-code">One-time code</label>
<input
id="one-time-code"
class="visual-example"
name="one-time-code"
inputmode="numeric"
autocomplete="one-time-code"
pattern="[0-9]{6}"
minlength="6"
maxlength="6"
size="6"
ng-model="otp"
required
/>
<output class="visually-hidden" aria-live="polite">
Code: {{ otp }}
</output>
</div>
</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. One native one-time-code input.
Anatomy
Root styling selector
input[autocomplete="one-time-code"]
Semantic structure
Use one native input with autocomplete="one-time-code". The standard autocomplete purpose identifies the segmented one-time-code presentation; input mode, length, and pattern remain native attributes.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
aria-invalid | Authored | Validation state exposed to assistive technology and CSS. |
group | Authored | Optional visual grouping size. Use 3 to separate a six-character code into two groups. |
maxlength | Authored | Maximum native text length. |
pattern | Authored | Native regular-expression validation constraint. |
size | Authored | Native visible-character count; AngularCSS supports four or six code cells. |
Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.
CSS custom properties
| Variable | Purpose |
|---|---|
--otp-cell-size | Width of one visual code cell; defaults to eight spacing units. |
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 OTP is one styling-only native input. The browser owns typing, editing, paste, password-manager autofill, autocomplete=one-time-code, input mode, length, pattern validation, and form submission; AngularTS ng-model owns application state. AngularCSS registers no input-otp directive.
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.
18 - item
Items compose media, content, title, description, and actions.
<div variant="outline" class="item">
<section>
<h3>Item title</h3>
<p>Supporting description.</p>
</section>
</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 Item</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>
<ul style="max-width: 32rem">
<li variant="outline" id="outline-item" class="item">
<figure variant="icon">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.75"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
/>
</svg>
</figure>
<section>
<h3>Profile verified</h3>
<p>Your public display name and email have been confirmed.</p>
</section>
<menu>
<button variant="outline" size="sm">Review</button>
</menu>
</li>
<li variant="muted" size="sm" id="compact-item" class="item">
<section>
<h3>Scheduled reports</h3>
<p>Weekly snapshots are ready for your team.</p>
</section>
<menu>
<span variant="secondary" class="badge">New</span>
</menu>
</li>
<li aria-disabled="true" id="disabled-item" class="item">
<section>
<h3>Archived workspace</h3>
<p>This workspace is retained for audit history.</p>
</section>
<menu>
<button variant="outline" size="sm" disabled>Restore</button>
</menu>
</li>
</ul>
</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 Item 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="itemState={message:'Ready'}">
<main class="item-workflow-grid" aria-label="Item workflows">
<section data-example="item-demo" class="item-workflow">
<ul>
<li variant="outline" class="item">
<section>
<h3>Basic Item</h3>
<p>A simple item with title and description.</p>
</section>
<menu>
<button
variant="outline"
size="sm"
type="button"
ng-click="itemState.message='Basic action'"
>
Action
</button>
</menu>
</li>
<li variant="outline" size="sm" href="#verified" class="item">
<figure>
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M9 12.75 11.25 15 15 9.75"></path>
<circle cx="12" cy="12" r="9"></circle>
</svg>
</figure>
<section>
<h3>Your profile has been verified.</h3>
</section>
<menu aria-hidden="true">›</menu>
</li>
</ul>
</section>
<section data-example="item-avatar" class="item-workflow">
<ul>
<li variant="outline" class="item">
<figure>
<span class="item-avatar-large avatar"
><img src="../../images/avatars/01.png" alt="Evil Rabbit"
/></span>
</figure>
<section>
<h3>Evil Rabbit</h3>
<p>Last seen 5 months ago</p>
</section>
<menu>
<button
variant="outline"
size="icon-sm"
type="button"
aria-label="Invite Evil Rabbit"
>
+
</button>
</menu>
</li>
<li variant="outline" class="item">
<figure class="item-avatar-stack">
<span class="avatar"
><img
src="../../images/avatars/02.png"
alt="Jordan Lee" /></span
><span class="avatar"
><img src="../../images/avatars/03.png" alt="maxleiter" /></span
><span class="avatar"
><img src="../../images/avatars/01.png" alt="evilrabbit"
/></span>
</figure>
<section>
<h3>No Team Members</h3>
<p>Invite your team to collaborate on this project.</p>
</section>
<menu>
<button
variant="outline"
size="sm"
type="button"
ng-click="itemState.message='Invite opened'"
>
Invite
</button>
</menu>
</li>
</ul>
</section>
<section data-example="item-icon" class="item-workflow">
<article variant="outline" class="item">
<figure variant="icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path
d="M12 9v4m0 4h.01M10.3 3.7 2.5 17.2A2 2 0 0 0 4.2 20h15.6a2 2 0 0 0 1.7-2.8L13.7 3.7a2 2 0 0 0-3.4 0Z"
></path>
</svg>
</figure>
<section>
<h3>Security Alert</h3>
<p>New login detected from unknown device.</p>
</section>
<menu>
<button variant="outline" size="sm" type="button">Review</button>
</menu>
</article>
</section>
<section data-example="item-image" class="item-workflow">
<ul>
<li variant="outline" href="#midnight" class="item">
<figure variant="image">
<img
src="../../images/avatars/01.png"
alt="Midnight City Lights"
/>
</figure>
<section>
<h3>Midnight City Lights - Electric Nights</h3>
<p>Neon Dreams</p>
</section>
<section>
<p>3:45</p>
</section>
</li>
<li variant="outline" href="#coffee" class="item">
<figure variant="image">
<img
src="../../images/avatars/02.png"
alt="Coffee Shop Conversations"
/>
</figure>
<section>
<h3>Coffee Shop Conversations - Urban Stories</h3>
<p>The Morning Brew</p>
</section>
<section>
<p>4:05</p>
</section>
</li>
<li variant="outline" href="#digital" class="item">
<figure variant="image">
<img src="../../images/avatars/03.png" alt="Digital Rain" />
</figure>
<section>
<h3>Digital Rain - Binary Beats</h3>
<p>Cyber Symphony</p>
</section>
<section>
<p>3:30</p>
</section>
</li>
</ul>
</section>
<section
data-example="item-dropdown"
class="item-workflow item-dropdown-workflow"
>
<div ng-dropdown-menu>
<button variant="outline" type="button">
Select <span aria-hidden="true">⌄</span>
</button>
<menu>
<section>
<button ng-click="itemState.message='Selected Jordan Lee'">
<article size="xs" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/02.png" alt=""
/></span>
</figure>
<section>
<h3>Jordan Lee</h3>
<p>jordan@example.com</p>
</section>
</article></button
><button ng-click="itemState.message='Selected maxleiter'">
<article size="xs" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/03.png" alt=""
/></span>
</figure>
<section>
<h3>maxleiter</h3>
<p>maxleiter@vercel.com</p>
</section>
</article></button
><button ng-click="itemState.message='Selected evilrabbit'">
<article size="xs" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/01.png" alt=""
/></span>
</figure>
<section>
<h3>evilrabbit</h3>
<p>evilrabbit@vercel.com</p>
</section>
</article>
</button>
</section>
</menu>
</div>
</section>
<section data-example="item-group" class="item-workflow">
<ul>
<li variant="outline" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/02.png" alt="Jordan Lee"
/></span>
</figure>
<section>
<h3>Jordan Lee</h3>
<p>jordan@example.com</p>
</section>
<menu>
<button
variant="ghost"
size="icon-sm"
type="button"
aria-label="Invite Jordan Lee"
>
+
</button>
</menu>
</li>
<li variant="outline" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/03.png" alt="maxleiter"
/></span>
</figure>
<section>
<h3>maxleiter</h3>
<p>maxleiter@vercel.com</p>
</section>
<menu>
<button
variant="ghost"
size="icon-sm"
type="button"
aria-label="Invite maxleiter"
>
+
</button>
</menu>
</li>
<li variant="outline" class="item">
<figure>
<span class="avatar"
><img src="../../images/avatars/01.png" alt="evilrabbit"
/></span>
</figure>
<section>
<h3>evilrabbit</h3>
<p>evilrabbit@vercel.com</p>
</section>
<menu>
<button
variant="ghost"
size="icon-sm"
type="button"
aria-label="Invite evilrabbit"
>
+
</button>
</menu>
</li>
</ul>
</section>
<section
data-example="item-header"
class="item-workflow item-workflow-wide"
>
<ul class="item-header-grid">
<li variant="outline" class="item">
<header class="item-header">
<img src="../../images/avatars/01.png" alt="v0-1.5-sm" />
</header>
<section>
<h3>v0-1.5-sm</h3>
<p>Everyday tasks and UI generation.</p>
</section>
</li>
<li variant="outline" class="item">
<header class="item-header">
<img src="../../images/avatars/02.png" alt="v0-1.5-lg" />
</header>
<section>
<h3>v0-1.5-lg</h3>
<p>Advanced thinking or reasoning.</p>
</section>
</li>
<li variant="outline" class="item">
<header class="item-header">
<img src="../../images/avatars/03.png" alt="v0-2.0-mini" />
</header>
<section>
<h3>v0-2.0-mini</h3>
<p>Open Source model for everyone.</p>
</section>
</li>
</ul>
</section>
<section data-example="item-link" class="item-workflow">
<ul>
<li href="#documentation" class="item">
<section>
<h3>Visit our documentation</h3>
<p>Learn how to get started with our components.</p>
</section>
<menu aria-hidden="true">›</menu>
</li>
<li variant="outline" href="#external" class="item">
<section>
<h3>External resource</h3>
<p>Opens in a new tab with security attributes.</p>
</section>
<menu aria-hidden="true">↗</menu>
</li>
</ul>
</section>
<section data-example="item-size" class="item-workflow">
<ul>
<li variant="outline" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Default Size</h3>
<p>The standard size for most use cases.</p>
</section>
</li>
<li variant="outline" size="sm" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Small Size</h3>
<p>A compact size for dense layouts.</p>
</section>
</li>
<li variant="outline" size="xs" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Extra Small Size</h3>
<p>The most compact size available.</p>
</section>
</li>
</ul>
</section>
<section data-example="item-variant" class="item-workflow">
<ul>
<li class="item">
<figure variant="icon">□</figure>
<section>
<h3>Default Variant</h3>
<p>Transparent background with no border.</p>
</section>
</li>
<li variant="outline" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Outline Variant</h3>
<p>Outlined style with a visible border.</p>
</section>
</li>
<li variant="muted" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Muted Variant</h3>
<p>Muted background for secondary content.</p>
</section>
</li>
</ul>
</section>
<section data-example="muted-item-group" class="item-workflow">
<ul>
<li variant="muted" ng-repeat="number in [1,2,3]" class="item">
<section>
<h3>Item {{ number }}</h3>
<p>Item in muted group.</p>
</section>
<menu>
<button variant="outline" size="sm" type="button">Action</button>
</menu>
</li>
</ul>
</section>
<section data-example="outline-item-group" class="item-workflow">
<ul>
<li variant="outline" ng-repeat="number in [1,2,3]" class="item">
<figure variant="icon">□</figure>
<section>
<h3>Item {{ number }}</h3>
<p>Item with icon.</p>
</section>
</li>
</ul>
</section>
<section
data-example="file-upload-list"
class="item-workflow item-workflow-wide"
>
<ul>
<li
size="xs"
class="file-upload-item item"
ng-repeat="file in [{name:'document.pdf',progress:45,time:'2m 30s'},{name:'presentation.pptx',progress:78,time:'45s'},{name:'spreadsheet.xlsx',progress:12,time:'5m 12s'},{name:'image.jpg',progress:100,time:'Complete'}]"
>
<figure variant="icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"
></path>
<path d="M14 2v6h6"></path>
</svg>
</figure>
<section>
<h3>{{ file.name }}</h3>
</section>
<section class="file-upload-progress">
<progress
value="{{ file.progress }}"
max="100"
aria-label="Upload progress for {{ file.name }}"
></progress>
</section>
<menu class="file-upload-time">{{ file.time }}</menu>
</li>
</ul>
</section>
<section
data-example="item-rtl"
class="item-workflow"
dir="rtl"
lang="ar"
>
<ul>
<li variant="outline" class="item">
<section>
<h3>عنصر أساسي</h3>
<p>عنصر بسيط يحتوي على عنوان ووصف.</p>
</section>
<menu>
<button variant="outline" size="sm" type="button">إجراء</button>
</menu>
</li>
<li variant="outline" size="sm" href="#verified-rtl" class="item">
<figure>✓</figure>
<section>
<h3>تم التحقق من ملفك الشخصي.</h3>
</section>
<menu aria-hidden="true">‹</menu>
</li>
</ul>
</section>
<output class="item-workflow-output">{{ itemState.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. Semantic repeated-content composition.
Anatomy
Root styling selector
.item
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 |
|---|---|---|
size | Authored | Item density: xs or sm; omit for the default size. |
variant | Authored | Item surface: outline or muted; direct figures additionally accept icon or image. |
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
Semantic repeated-content composition. 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.
19 - pagination
Use nav with aria-label="pagination" and mark the current page with
aria-current="page".
<nav aria-label="pagination" class="pagination">
<ul>
<li>
<a href="#">1</a>
</li>
<li>
<a aria-current="page" href="#">2</a>
</li>
</ul>
</nav>
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 Pagination</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="pagination-demo">
<main class="visual-example">
<nav aria-label="pagination" class="pagination">
<ul>
<li>
<a href="#previous" rel="prev" aria-label="Go to previous page">
<svg
icon="inline-start"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m15 18-6-6 6-6"></path>
</svg>
<span>Previous</span>
</a>
</li>
<li>
<a href="#page-1">1</a>
</li>
<li>
<a href="#page-2" aria-current="page">2</a>
</li>
<li>
<a href="#page-3">3</a>
</li>
<li>
<span aria-hidden="true">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor">
<circle cx="5" cy="12" r="1.5"></circle>
<circle cx="12" cy="12" r="1.5"></circle>
<circle cx="19" cy="12" r="1.5"></circle>
</svg>
<span>More pages</span>
</span>
</li>
<li>
<a href="#next" rel="next" aria-label="Go to next page">
<span>Next</span>
<svg
icon="inline-end"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m9 18 6-6-6-6"></path>
</svg>
</a>
</li>
</ul>
</nav>
</main>
</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 Pagination 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="paginationWorkflow={showPage4:false,activePage:2,nextDisabled:false,rows:'25'}"
data-example="pagination-icons-only pagination-rtl pagination-simple"
>
<main class="visual-example">
<section aria-labelledby="pagination-dynamic-heading">
<header>
<h2 id="pagination-dynamic-heading">Application state</h2>
<div class="component-state-actions">
<button
type="button"
variant="outline"
size="sm"
ng-click="paginationWorkflow.showPage4=!paginationWorkflow.showPage4; paginationWorkflow.activePage=paginationWorkflow.showPage4 ? 4 : 2"
>
{{ paginationWorkflow.showPage4 ? 'Remove page 4' : 'Add page 4'
}}
</button>
<button
type="button"
variant="outline"
size="sm"
ng-click="paginationWorkflow.nextDisabled=!paginationWorkflow.nextDisabled"
>
{{ paginationWorkflow.nextDisabled ? 'Enable next' : 'Disable
next' }}
</button>
</div>
</header>
<nav
aria-label="Dynamic pagination"
id="dynamic-pagination"
class="pagination"
>
<ul>
<li>
<a
href="#page-1"
ng-click="paginationWorkflow.activePage=1"
aria-current="{{ paginationWorkflow.activePage === 1 ? 'page' : 'false' }}"
>1</a
>
</li>
<li>
<a
href="#page-2"
ng-click="paginationWorkflow.activePage=2"
aria-current="{{ paginationWorkflow.activePage === 2 ? 'page' : 'false' }}"
>2</a
>
</li>
<li>
<a
href="#page-3"
ng-click="paginationWorkflow.activePage=3"
aria-current="{{ paginationWorkflow.activePage === 3 ? 'page' : 'false' }}"
>3</a
>
</li>
<li ng-if="paginationWorkflow.showPage4">
<a
href="#page-4"
ng-click="paginationWorkflow.activePage=4"
aria-current="{{ paginationWorkflow.activePage === 4 ? 'page' : 'false' }}"
>4</a
>
</li>
<li>
<a
href="#next"
rel="next"
aria-label="Go to next page"
aria-disabled="{{ paginationWorkflow.nextDisabled }}"
>
<span>Next</span>
<svg
icon="inline-end"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m9 18 6-6-6-6"></path>
</svg>
</a>
</li>
</ul>
</nav>
</section>
<section aria-labelledby="pagination-simple-heading">
<header>
<h2 id="pagination-simple-heading">Simple</h2>
</header>
<nav aria-label="Simple pagination" class="pagination">
<ul>
<li>
<a href="#simple-1">1</a>
</li>
<li>
<a href="#simple-2" aria-current="page">2</a>
</li>
<li>
<a href="#simple-3">3</a>
</li>
<li>
<a href="#simple-4">4</a>
</li>
<li>
<a href="#simple-5">5</a>
</li>
</ul>
</nav>
</section>
<section aria-labelledby="pagination-icons-heading">
<header>
<h2 id="pagination-icons-heading">Rows</h2>
</header>
<div class="pagination-compact-row">
<label class="pagination-rows-field" for="pagination-rows-per-page">
<span>Rows per page</span>
<select
id="pagination-rows-per-page"
ng-model="paginationWorkflow.rows"
>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</label>
<nav aria-label="Compact pagination" class="pagination">
<ul>
<li>
<a
href="#compact-previous"
rel="prev"
aria-label="Go to previous page"
>
<svg
icon="inline-start"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m15 18-6-6 6-6"></path>
</svg>
</a>
</li>
<li>
<a href="#compact-next" rel="next" aria-label="Go to next page">
<svg
icon="inline-end"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m9 18 6-6-6-6"></path>
</svg>
</a>
</li>
</ul>
</nav>
</div>
<output class="workflow-output">
Rows: <span ng-bind="paginationWorkflow.rows"></span>
</output>
</section>
<section aria-labelledby="pagination-rtl-heading" lang="ar">
<header>
<h2 id="pagination-rtl-heading">الصفحات</h2>
</header>
<nav
dir="rtl"
aria-label="ترقيم الصفحات"
id="rtl-pagination"
class="pagination"
>
<ul>
<li>
<a
href="#rtl-previous"
rel="prev"
aria-label="الانتقال إلى الصفحة السابقة"
>
<svg
icon="inline-start"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m15 18-6-6 6-6"></path>
</svg>
<span>السابق</span>
</a>
</li>
<li>
<a href="#rtl-1">١</a>
</li>
<li>
<a href="#rtl-2" aria-current="page">٢</a>
</li>
<li>
<a href="#rtl-3">٣</a>
</li>
<li>
<span>
<svg aria-hidden="true" viewBox="0 0 24 24" fill="currentColor">
<circle cx="5" cy="12" r="1.5"></circle>
<circle cx="12" cy="12" r="1.5"></circle>
<circle cx="19" cy="12" r="1.5"></circle>
</svg>
<span>صفحات إضافية</span>
</span>
</li>
<li>
<a
href="#rtl-next"
rel="next"
aria-label="الانتقال إلى الصفحة التالية"
>
<span>التالي</span>
<svg
icon="inline-end"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="m9 18 6-6-6-6"></path>
</svg>
</a>
</li>
</ul>
</nav>
</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 navigation, lists, and links.
Anatomy
Root styling selector
.pagination
Semantic structure
Apply .pagination to a native nav containing a ul or ol with direct li children. The class distinguishes Pagination from other navigation landmarks; page, previous, and next controls remain native links. Ellipsis is optional. Compose rows-per-page controls beside Pagination with existing native form components; Pagination does not own that model.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
aria-current | Authored | Current item or date state. |
aria-disabled | Authored | Semantic disabled state. |
dir | Authored | Text and interaction direction: ltr or rtl. |
rel | Authored | Use the prev or next link type for directional pagination controls. |
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 navigation, lists, list items, and links own pagination semantics and navigation. URLs, routing, page counts, rows-per-page values, and current-page application state remain AngularTS or application concerns. AngularCSS registers no pagination directive.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use a native nav landmark with an accessible label, a native list, and native links. Expose exactly one current destination with aria-current="page". Previous and next links need destination-specific accessible names; ellipsis is decorative and removed from the accessibility tree.
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.
20 - popover
Connect a native button to semantic popover content with popovertarget and
popover. The browser owns top-layer rendering, Escape, and light dismissal.
<span>
<button popovertarget="dimensions">Open</button>
<aside id="dimensions" popover>Content</aside>
</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 Popover</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="popover-demo">
<main class="visual-example">
<span aria-label="Dimensions popover">
<button
type="button"
variant="outline"
popovertarget="popover-popover-1-content"
>
Open popover
</button>
<aside
aria-label="Dimensions"
id="popover-popover-1-content"
side="bottom"
align="center"
popover
>
<header>
<h2>Dimensions</h2>
<p>Set the dimensions for the layer.</p>
</header>
<form>
<label
><span>Width</span>
<input id="popover-width" value="100%" autofocus />
</label>
<label
><span>Max. width</span>
<input id="popover-max-width" value="300px" />
</label>
<label
><span>Height</span>
<input id="popover-height" value="25px" />
</label>
<label
><span>Max. height</span>
<input id="popover-max-height" value="none" />
</label>
</form>
</aside>
</span>
</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 Popover API disclosure.
Anatomy
Root styling selector
span:has(> [popovertarget] ~ [popover])
Semantic structure
Connect a native button’s popovertarget to one element with the matching id and popover. Header, title, and description selectors are optional styling hooks. Use native form controls inside the content; AngularTS owns their values and validation.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
align | Authored | Popover alignment: start, center, or end. |
popover | Authored | Native Popover API state and behavior on the surface. |
popovertarget | Authored | ID of the sibling popover controlled by the trigger. |
side | Authored | Preferred placement: top, right, bottom, or left. |
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 Popover API owns non-modal disclosure, top-layer rendering, outside pointer dismissal, and Escape closure. popovertarget connects the invoker to the popover element. AngularTS remains responsible for authored content, form values, and application state.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use a native button invoker and give the popover content a useful accessible name when its context is not otherwise clear. Escape and pointer light-dismiss are browser behavior; add autofocus only when moving focus into the content is appropriate.
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.
21 - skeleton
Use class="skeleton" on a block element and control its size with normal CSS.
<div
style="height: 2.5rem; width: 2.5rem; border-radius: 9999px;"
class="skeleton"
></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 Skeleton</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="skeleton-avatar skeleton-card skeleton-demo skeleton-form skeleton-rtl skeleton-table skeleton-text"
>
<main aria-label="Skeleton examples">
<section
class="skeleton-demo visual-example"
aria-label="Loading profile preview"
>
<output
id="labeled-skeleton"
aria-label="Loading avatar"
aria-hidden="false"
style="width: 3rem; height: 3rem; border-radius: 9999px"
class="skeleton"
></output>
<div class="skeleton-lines">
<div
id="decorative-skeleton"
aria-hidden="true"
style="width: 15.625rem; height: 1rem"
class="skeleton"
></div>
<div
aria-hidden="true"
style="width: 12.5rem; height: 1rem"
class="skeleton"
></div>
</div>
</section>
<section class="skeleton-card-demo" aria-label="Loading card">
<div class="skeleton-card-media skeleton"></div>
<div class="skeleton-line-wide skeleton"></div>
<div class="skeleton-line-medium skeleton"></div>
<div class="skeleton-button-placeholder skeleton"></div>
</section>
<section class="skeleton-form-demo" aria-label="Loading form">
<div>
<div class="skeleton-label-placeholder skeleton"></div>
<div class="skeleton-input-placeholder skeleton"></div>
</div>
<div>
<div class="skeleton-label-placeholder skeleton"></div>
<div class="skeleton-input-placeholder skeleton"></div>
</div>
<div class="skeleton-button-placeholder skeleton"></div>
</section>
<section class="skeleton-table-demo" aria-label="Loading table">
<div class="skeleton-table-heading skeleton"></div>
<div class="skeleton-table-row">
<div class="skeleton"></div>
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
<div class="skeleton-table-row">
<div class="skeleton"></div>
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
<div class="skeleton-table-row">
<div class="skeleton"></div>
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
</section>
<section class="skeleton-text-demo" aria-label="Loading text">
<div class="skeleton-line-wide skeleton"></div>
<div class="skeleton-line-wide skeleton"></div>
<div class="skeleton-line-medium skeleton"></div>
</section>
<section
class="skeleton-rtl-demo"
aria-label="تحميل الملف الشخصي"
dir="rtl"
lang="ar"
>
<div class="skeleton-avatar-placeholder skeleton"></div>
<div>
<div class="skeleton-line-wide skeleton"></div>
<div class="skeleton-line-medium skeleton"></div>
</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. Authored loading placeholder.
Anatomy
Root styling selector
.skeleton
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
Authored loading placeholder. 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 the appropriate live-region or status semantics for dynamic feedback. Decorative feedback must stay hidden from assistive technology.
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.
22 - spinner
Use class="spinner" on an SVG with an accessible label. Place it in an
output when status semantics are needed.
<svg aria-label="Loading" viewBox="0 0 24 24" class="spinner">
<circle cx="12" cy="12" r="10" />
</svg>
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 Spinner</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="spinner-demo">
<div class="visual-example">
<article variant="muted" class="item">
<figure>
<svg
viewBox="0 0 24 24"
fill="none"
aria-live="polite"
aria-label="Loading"
aria-busy="true"
class="spinner"
>
<path
d="M21 12a9 9 0 1 1-6.22-8.56"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
</figure>
<section>
<h3>Processing payment...</h3>
</section>
<section class="spinner-amount">
<span>$100.00</span>
</section>
</article>
</div>
</body>
</html>
Composition 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 Spinner 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="spinner-badge spinner-button spinner-custom spinner-empty spinner-input-group spinner-rtl spinner-size input-group-spinner"
>
<main class="spinner-workflows">
<div class="workflow-row" aria-label="Spinner sizes">
<svg
id="processing-spinner"
aria-live="assertive"
aria-label="Processing data"
style="width: 12px; height: 12px"
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>
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" class="spinner">
<path
d="M21 12a9 9 0 1 1-6.22-8.56"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<svg
aria-hidden="true"
style="width: 24px; height: 24px"
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>
<svg
aria-hidden="true"
style="width: 32px; height: 32px"
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>
</div>
<div class="workflow-row" aria-label="Spinner badges">
<span class="badge"
><svg
icon="inline-start"
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
>Syncing</span
>
<span variant="secondary" class="badge"
><svg
icon="inline-start"
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
>Updating</span
>
<span variant="outline" class="badge"
><svg
icon="inline-start"
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
>Processing</span
>
</div>
<div class="workflow-buttons-column" aria-label="Spinner buttons">
<button disabled size="sm">
<svg
icon="inline-start"
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
>Loading...
</button>
<button variant="outline" disabled size="sm">
<svg
icon="inline-start"
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
>Please wait
</button>
<button variant="secondary" disabled size="sm">
<svg
icon="inline-start"
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
>Processing
</button>
</div>
<section class="spinner-empty-demo empty" aria-live="polite">
<header>
<figure variant="icon">
<svg 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>
</figure>
<h2>Processing your request</h2>
<p>
Please wait while we process your request. Do not refresh the page.
</p>
</header>
<section>
<button variant="outline" size="sm">Cancel</button>
</section>
</section>
<div class="workflow-input-groups" aria-label="Spinner input groups">
<div class="input-group">
<input placeholder="Searching..." />
<div align="inline-end">
<svg 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>
</div>
</div>
<div class="input-group">
<input placeholder="Saving changes..." />
<div align="inline-end">
<span>Saving...</span
><svg 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>
</div>
</div>
</div>
<article variant="muted" class="spinner-rtl-demo item" dir="rtl">
<figure>
<svg 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>
</figure>
<section>
<h3>جاري معالجة الدفع...</h3>
</section>
<section class="spinner-amount">
<span>١٠٠.٠٠ دولار</span>
</section>
</article>
</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. Authored status indicator.
Anatomy
Root styling selector
.spinner
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 |
|---|---|---|
size | Authored | Spinner size: sm or lg; 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
Authored status indicator. 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 the appropriate live-region or status semantics for dynamic feedback. Decorative feedback must stay hidden from assistive technology.
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.
23 - stepper
Present workflow progress as an ordered list inside navigation. The current step
is authored with aria-current="step"; routing and workflow state remain
application-owned.
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 Stepper</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="stepper-demo">
<nav class="visual-example" aria-label="Create customer">
<ol>
<li><a href="#account">Account</a></li>
<li><a href="#contacts" aria-current="step">Contacts</a></li>
<li><span>Permissions</span></li>
<li><span>Review</span></li>
</ol>
</nav>
</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 ordered workflow navigation.
Anatomy
Root styling selector
nav:has([aria-current="step"])
Semantic structure
Use a native nav containing one direct ordered list. Each item contains a link or text span, and aria-current=step on the current item identifies the Stepper without a class.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
aria-current | Authored | Current item or date 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
Stepper styles native ordered navigation and derives completed presentation from the authored current step. AngularTS or routing owns workflow progress and whether a destination is available.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Use an ordered list inside a labeled navigation landmark. Apply aria-current=step to exactly one link or text label and do not make unavailable steps interactive.
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.
24 - toggle
aria-pressed state.Use a native button with authored aria-pressed state. That state identifies
the control as a toggle and supplies its styling hook.
<button aria-pressed="true">Bold</button>
<button variant="outline" aria-pressed="false">Italic</button>
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 Toggle</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="bookmark=false;bold=false;italic=true"
data-example="toggle-demo toggle-outline toggle-sizes toggle-text"
>
<main class="visual-example">
<div class="row" aria-label="Bookmark toggle">
<button
variant="outline"
size="sm"
aria-label="Toggle bookmark"
aria-pressed="{{ bookmark }}"
ng-click="bookmark = !bookmark"
type="button"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M6 3h12v18l-6-4-6 4z" />
</svg>
Bookmark
</button>
</div>
<div class="row" aria-label="Text toggles">
<button
aria-label="Toggle italic text"
aria-pressed="{{ italic }}"
ng-click="italic = !italic"
type="button"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M10 4h7M7 20h7M14 4 10 20" />
</svg>
Italic
</button>
</div>
<div class="row" aria-label="Outline toggles">
<button
variant="outline"
aria-label="Toggle italic"
aria-pressed="{{ italic }}"
ng-click="italic = !italic"
type="button"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M10 4h7M7 20h7M14 4 10 20" />
</svg>
Italic
</button>
<button
variant="outline"
aria-label="Toggle bold"
aria-pressed="{{ bold }}"
ng-click="bold = !bold"
type="button"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M6 4h7a4 4 0 0 1 0 8H6zM6 12h8a4 4 0 0 1 0 8H6z" />
</svg>
Bold
</button>
</div>
<div class="row" aria-label="Toggle sizes">
<button variant="outline" size="sm" type="button" aria-pressed="false">
Small
</button>
<button variant="outline" type="button" aria-pressed="false">
Default
</button>
<button variant="outline" size="lg" type="button" aria-pressed="false">
Large
</button>
</div>
<output class="output">
Bookmark: {{ bookmark ? 'on' : 'off' }}, Bold: {{ bold ? 'on' : 'off'
}}, Italic: {{ italic ? 'on' : 'off' }}
</output>
</main>
</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 Toggle 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="disabledState = true; rtlBookmark = false"
data-example="toggle-disabled toggle-rtl"
>
<main class="component-state-grid visual-example">
<section
class="component-state-section"
aria-labelledby="toggle-disabled-heading"
>
<h2 id="toggle-disabled-heading">Disabled</h2>
<div class="row">
<button
type="button"
ng-disabled="disabledState"
aria-pressed="false"
>
Disabled
</button>
<button
type="button"
variant="outline"
ng-disabled="disabledState"
aria-pressed="false"
>
Disabled
</button>
</div>
<button
type="button"
variant="outline"
size="sm"
ng-click="disabledState = !disabledState"
>
{{ disabledState ? 'Enable toggles' : 'Disable toggles' }}
</button>
</section>
<section
class="component-state-section"
aria-labelledby="toggle-rtl-heading"
dir="rtl"
lang="ar"
>
<h2 id="toggle-rtl-heading">إشارة مرجعية</h2>
<button
type="button"
size="sm"
variant="outline"
aria-label="تبديل الإشارة المرجعية"
aria-pressed="{{ rtlBookmark }}"
ng-click="rtlBookmark = !rtlBookmark"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path d="M6 3h12v18l-6-4-6 4z" />
</svg>
إشارة مرجعية
</button>
<output class="output">
الحالة: {{ rtlBookmark ? 'مفعلة' : 'غير مفعلة' }}
</output>
</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 button pressed state.
Anatomy
Root styling selector
button[aria-pressed]
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-pressed | Authored | Pressed state of a toggle control. |
size | Authored | Toggle size: sm or lg; omit for the default size. |
variant | Authored | Toggle presentation: outline; omit for the default style. |
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 pressed state. 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.
25 - toggle-group
Use radios sharing a name for single selection, or checkboxes for independent multiple selection.
<fieldset variant="outline" class="toggle-group">
<legend class="visually-hidden">Alignment</legend>
<label>
<input type="radio" name="alignment" value="left" ng-model="alignment" />
Left
</label>
<label>
<input type="radio" name="alignment" value="center" ng-model="alignment" />
Center
</label>
</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 Toggle 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="alignment='center'">
<div class="stack-sm">
<fieldset class="toggle-group visual-example" variant="outline">
<legend class="visually-hidden">Text alignment</legend>
<label>
<input
type="radio"
name="alignment"
value="left"
ng-model="alignment"
/>
Left
</label>
<label>
<input
type="radio"
name="alignment"
value="center"
ng-model="alignment"
/>
Center
</label>
<label>
<input
type="radio"
name="alignment"
value="right"
ng-model="alignment"
/>
Right
</label>
</fieldset>
<output class="output">
Alignment: <span ng-bind="alignment"></span>
</output>
</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 Toggle 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="fontWeight='normal'; pageDirection='rtl'; bold=true; italic=true"
data-example="toggle-group-demo toggle-group-disabled toggle-group-font-weight-selector toggle-group-outline toggle-group-rtl toggle-group-sizes toggle-group-spacing toggle-group-vertical"
>
<main class="toggle-group-workflows visual-example">
<section aria-labelledby="toggle-format-heading">
<header><h2 id="toggle-format-heading">Formatting</h2></header>
<fieldset
class="toggle-group"
variant="outline"
id="multiple-toggle-group"
>
<legend class="visually-hidden">Text formatting</legend>
<label><input type="checkbox" ng-model="bold" />Bold</label>
<label><input type="checkbox" ng-model="italic" />Italic</label>
<label><input type="checkbox" />Underline</label>
</fieldset>
</section>
<section aria-labelledby="toggle-keyboard-heading">
<header>
<h2 id="toggle-keyboard-heading">Keyboard navigation</h2>
</header>
<fieldset
class="toggle-group"
variant="outline"
id="keyboard-toggle-group"
>
<legend class="visually-hidden">Text style</legend>
<label
><input type="radio" name="style" value="bold" checked />Bold</label
>
<label
><input
type="radio"
name="style"
value="italic"
disabled
/>Italic</label
>
<label
><input
type="radio"
name="style"
value="underline"
/>Underline</label
>
</fieldset>
</section>
<section aria-labelledby="toggle-disabled-heading">
<header><h2 id="toggle-disabled-heading">Disabled</h2></header>
<fieldset class="toggle-group" id="disabled-toggle-group" disabled>
<legend class="visually-hidden">Disabled formatting</legend>
<label><input type="checkbox" />Bold</label>
<label><input type="checkbox" />Italic</label>
<label><input type="checkbox" />Underline</label>
</fieldset>
</section>
<section aria-labelledby="toggle-weight-heading">
<header><h2 id="toggle-weight-heading">Font weight</h2></header>
<fieldset
class="toggle-group"
variant="outline"
spacing="2"
size="lg"
id="font-weight-toggle-group"
>
<legend class="visually-hidden">Font weight</legend>
<label class="toggle-weight-item"
><input
type="radio"
name="weight"
value="light"
ng-model="fontWeight"
/><strong style="font-weight: 300">Aa</strong
><span>Light</span></label
>
<label class="toggle-weight-item"
><input
type="radio"
name="weight"
value="normal"
ng-model="fontWeight"
/><strong style="font-weight: 400">Aa</strong
><span>Normal</span></label
>
<label class="toggle-weight-item"
><input
type="radio"
name="weight"
value="medium"
ng-model="fontWeight"
/><strong style="font-weight: 500">Aa</strong
><span>Medium</span></label
>
<label class="toggle-weight-item"
><input
type="radio"
name="weight"
value="bold"
ng-model="fontWeight"
/><strong style="font-weight: 700">Aa</strong
><span>Bold</span></label
>
</fieldset>
<output class="output">Selected: font-{{ fontWeight }}</output>
</section>
<section aria-labelledby="toggle-sizes-heading">
<header><h2 id="toggle-sizes-heading">Sizes and spacing</h2></header>
<div class="toggle-group-size-stack">
<fieldset class="toggle-group" size="sm" variant="outline">
<legend class="visually-hidden">Small position</legend>
<label
><input type="radio" name="small-position" checked />Top</label
>
<label><input type="radio" name="small-position" />Bottom</label>
</fieldset>
<fieldset
class="toggle-group"
variant="outline"
spacing="2"
id="spaced-toggle-group"
>
<legend class="visually-hidden">Spaced position</legend>
<label
><input type="radio" name="spaced-position" checked />Top</label
>
<label><input type="radio" name="spaced-position" />Bottom</label>
</fieldset>
</div>
</section>
<section aria-labelledby="toggle-vertical-heading">
<header><h2 id="toggle-vertical-heading">Vertical</h2></header>
<fieldset
class="toggle-group"
orientation="vertical"
spacing="1"
id="vertical-toggle-group"
>
<legend class="visually-hidden">Vertical formatting</legend>
<label><input type="checkbox" checked />Bold</label>
<label><input type="checkbox" checked />Italic</label>
<label><input type="checkbox" />Underline</label>
</fieldset>
</section>
<section
dir="{{ pageDirection }}"
lang="ar"
id="toggle-rtl-shell"
aria-labelledby="toggle-rtl-heading"
>
<header>
<h2 id="toggle-rtl-heading">اتجاه العرض</h2>
<button
type="button"
variant="outline"
size="sm"
ng-click="pageDirection = pageDirection === 'rtl' ? 'ltr' : 'rtl'"
>
Change direction
</button>
</header>
<fieldset class="toggle-group" variant="outline" id="rtl-toggle-group">
<legend class="visually-hidden">طريقة العرض</legend>
<label
><input type="radio" name="view" value="list" checked />قائمة</label
>
<label><input type="radio" name="view" value="grid" />شبكة</label>
<label><input type="radio" name="view" value="cards" />بطاقات</label>
</fieldset>
</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 radio or checkbox grouping.
Anatomy
Root styling selector
.toggle-group
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 |
|---|---|---|
orientation | Authored | Group layout: vertical; omit for the horizontal layout. |
size | Authored | Control size: sm or lg; omit for the default size. |
spacing | Authored | Gap in spacing units: 1 or 2; omit to join controls. |
variant | Authored | Control presentation: outline; omit for the default style. |
Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.
CSS custom properties
| Variable | Purpose |
|---|---|
--toggle-group-gap | Gap between controls; defaults to 0. |
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
Toggle Group is a styling-only native fieldset: use radios sharing a name for single selection and checkboxes for multiple selection. The browser owns selection, arrow-key radio navigation, disabled state, focus, validation, and form submission; AngularTS ng-model owns application state. AngularCSS registers no toggle-group directive.
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.
26 - validation-summary
Place a validation summary before the related fields when submission reveals several errors. Each message links directly to its native form control.
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 Validation Summary</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="validation-summary-demo">
<main class="visual-example">
<aside role="alert" tabindex="-1">
<header>
<h2>There are two problems with this form</h2>
<p>Correct the fields below, then submit again.</p>
</header>
<ul>
<li><a href="#customer-name">Enter a customer name.</a></li>
<li><a href="#customer-email">Enter a valid email address.</a></li>
</ul>
</aside>
<form>
<label for="customer-name">Customer name</label>
<input id="customer-name" required />
<label for="customer-email">Email</label>
<input id="customer-email" type="email" required />
</form>
</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. Authored validation messages linked to form controls.
Anatomy
Root styling selector
aside[role="alert"]:has(> header + ul)
Semantic structure
Use role="alert" on a semantic aside containing a direct header followed by a list of links to invalid controls. No classes or part markers are required.
API
Attributes and state
| Attribute | Access | Purpose |
|---|---|---|
role | Authored | Explicit semantic role when native HTML does not provide one. |
tabindex | Authored | Keyboard focus order for composite descendants. |
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
Validation Summary presents authored error links. Native form validation, AngularTS form controllers, server responses, message visibility, and focus policy remain application-owned.
AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.
Accessibility
Give the summary a heading and link every message to its corresponding control. Use an alert or live region when errors appear after submission, then apply application focus policy deliberately.
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.