Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Accessibility in Angular – Angulars features for a better and more inclusive web

Accessibility in Angular – Angulars features for a better and more inclusive web

In this Talk at the Angular Berlin Meetup on January 16th 2024, Danny talked about some basics when it comes to creating accessible web applications.
He'd had a deeper look into the Angular Framework and the features it provides to us helping to improve the overall accessibility. Furthermore, he guided through the usage of the Angular CDK which provides additional tools helping us to improve the accessibility of our application.

Danny Koppenhagen

January 16, 2024
Tweet

Transcript

  1. Accessibility in Angular Angulars features for a better and more

    inclusive web DB Systel GmbH | Danny Koppenhagen | 16.01.2024
  2. Overview DB Systel GmbH | Danny Koppenhagen | 16.01.2024 3

    1. Introduction to a11y 2. Angulars a11y features 3. Angular CDK 4. Linting, Testing & Tools
  3. About me DB Systel GmbH | Danny Koppenhagen | 16.01.2024

    4 Danny Koppenhagen GitHub: d-koppenhagen (Twitter): @d_koppenhagen LinkedIn: d-koppenhagen
  4. Types of limitations DB Systel GmbH | Danny Koppenhagen |

    16.01.2024 6 type permanent temporary situational controlling only one arm broken arm parents with a child in their arms seeing blindness eye surgery distracted driver hearing deaf ear infection working on noisy machines speaking muteness laryngitis heavy accent thinking cognitive limitations headache distraction, fatigue
  5. W3C, WAI, WCAG DB Systel GmbH | Danny Koppenhagen |

    16.01.2024 7 World Wide Web Consortium WAI Web Accessibility Initiative publishes WCAG Web Content Accessibility Guidelines
  6. ARIA and Roles – Just a part of the solution

    DB Systel GmbH | Danny Koppenhagen | 16.01.2024 9 • Prefer always the usage of Semantic HTML elements! • Roles are already embedded in some elements (such as regions, details/summary, dialog, etc.) • ARIA attributes often not needed - aria-required ⟶ required - aria-hidden ⟶ hidden - aria-label ⟶ visual Text - aria-readonly ⟶ readonly - div[role=button] ⟶ <button>
  7. Choose your libs wisely DB Systel GmbH | Danny Koppenhagen

    | 16.01.2024 10 Project A Project B Project C Project N Inaccessible Library
  8. Template Syntax: ARIA Attributes DB Systel GmbH | Danny Koppenhagen

    | 16.01.2024 12 • Static ARIA attributes can be set directly <app-input aria-describedby="my-el"/> • Bindings must be made using the attr. prefix <app-input [attr.aria-describedby]="attr"/>
  9. Template Syntax: Deferred Loading DB Systel GmbH | Danny Koppenhagen

    | 16.01.2024 13 Keep aware, lazy loaded content must maybe announced when loading state changes <p aria-atomic="true" aria-live="polite"> @defer(on timer(10000)) { <app-my-heavy-comp/> } @placeholder() { Placeholder... } @loading(minimum 1000) { Loading... } @error() { Error... } </p> Announce whole content within, not only changed parts Set politeness
  10. ARIA Atomic DB Systel GmbH | Danny Koppenhagen | 16.01.2024

    14 <p role="timer" aria-atomic="true"> <span>10</span> seconds left. </p> <p role="timer" aria-atomic="true"> <span>9</span> seconds left. </p> „10 seconds left.“ „9 seconds left.“ <p role="timer"> <span>10</span> seconds left. </p> <p role="timer"> <span>9</span> seconds left. </p> „10“ „9“
  11. Track items by unique attribute DB Systel GmbH | Danny

    Koppenhagen | 16.01.2024 16 • Prevent DOM updates of the whole list • Restore on focus changes when rendering dynamic lists • Prevent errors when array is updated while interacting • Prevent using track $index @for(recipient of recipients; track recipient.id) { <address> DB Systel GmbH<br/> c/o {{ recipient.fullname }}<br/> Kynaststraße 1<br/> 10317 Berlin </address> }
  12. Angular Router: aria-current & active page styling DB Systel GmbH

    | Danny Koppenhagen | 16.01.2024 18 aria-current="page" • Angular Router has built-in mechanism to determine and style active pages • Current page indication with ARIA attribute aria-current
  13. Angular Router: Unique page titles DB Systel GmbH | Danny

    Koppenhagen | 16.01.2024 19 • Page title can be set in the route config entry • Custom / dynamic titles possible using the TitleStrategy Examples - / ➡ My Awesome Blog: Home - /blog ➡ My Awesome Blog: Latests Blog Posts - /blog/:slug ➡ My Awesome Blog: <Blog Post Title> Dynamic title fetched by service Title prefix added by TitleStrategy
  14. Listbox – General Focus Strategies DB Systel GmbH | Danny

    Koppenhagen | 16.01.2024 24 Roving Tabindex <label id="dropdown-label"> Dropdown </label> <ul aria-labelledby="dropdown-label" role="listbox"> <li role="option" tabindex="-1">#1</li> <li role="option" tabindex="0">#2</li> <li role="option" tabindex="-1">#3</li> </ul> Aria active decendant <label id="dropdown-label"> Dropdown </label> <ul aria-labelledby="dropdown-label" role="listbox" tabindex="0" aria-activedescendant="i2"> <li role="option" id="i1">#1</li> <li role="option" id="i2">#2</li> <li role="option" id="i3">#3</li> </ul>
  15. CDK Listbox DB Systel GmbH | Danny Koppenhagen | 16.01.2024

    25 <label id="dropdown-label"> Dropdown </label> <ul cdkListbox aria-labelledby="dropdown-label"> <li cdkOption="i1">#1</li> <li cdkOption="i2">#2</li> <li cdkOption="i3">#3</li> </ul>
  16. Overlay DB Systel GmbH | Danny Koppenhagen | 16.01.2024 27

    <cdk-overlay-container> … </cdk-overlay-container> is mounted in the apps <body> element Two strategies: • GlobalPositionStrategy: specific viewport position (for modals, appl-level notifications, etc.) • ConnectedPositionStrategy: placed relative to the origin (for menus, pickers, tooltips, etc.) • CDK Overlay is the most generic and flexible implementation • It‘s used / implemented by other CDK features such as Menu or Dialog
  17. Live Announcer DB Systel GmbH | Danny Koppenhagen | 16.01.2024

    28 • Creates a visually hidden aria-live region in the apps <body> element and inserts/updates conent within so the content/changes will be announced by screenreaders @Component({ //... }) export class MyComponent { constructor(liveAnnouncer: LiveAnnouncer) { liveAnnouncer.announce("Hello Angular Berlin Meetup!"); } }
  18. Strategies for hiding elements DB Systel GmbH | Danny Koppenhagen

    | 16.01.2024 29 For screenreaders <section aria-hidden="true"> For all <section hidden="true"> <section style="display: none;"> Only visual .visually-hidden:not(:focus):not(:active), .sr-only:not(:focus):not(:active) { height: 1px; overflow: hidden; width: 1px; position: absolute; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); white-space: nowrap; } shrink to 1px size remove visualiy (e. g. background) prevent wrapping content
  19. CKD helper: cdk-visually-hidden DB Systel GmbH | Danny Koppenhagen |

    16.01.2024 30 @use '@angular/cdk'; @include cdk.a11y-visually-hidden(); <div class="cdk-visually-hidden"> My visually hidden text </div>
  20. Trees DB Systel GmbH | Danny Koppenhagen | 16.01.2024 32

    • Build (expandable) tree structures • Sets role="tree", role="treeitem" automatically Demos: https://k9n.dev/blog/2020-11-twa (Open the navigation on the right site) https://material.angular.io/cdk/tree/examples
  21. ESLint DB Systel GmbH | Danny Koppenhagen | 16.01.2024 35

    ng add @angular-eslint/schematics npm run lint .eslintrc.json is created and pre-configured including the following accessibility rules: "@angular-eslint/template/alt-text": "error", "@angular-eslint/template/click-events-have-key-events": "error", "@angular-eslint/template/elements-content": "error", "@angular-eslint/template/interactive-supports-focus": "error", "@angular-eslint/template/label-has-associated-control": "error", "@angular-eslint/template/mouse-events-have-key-events": "error", "@angular-eslint/template/no-autofocus": "error", "@angular-eslint/template/no-distracting-elements": "error", "@angular-eslint/template/role-has-required-aria": "error", "@angular-eslint/template/table-scope": "error", "@angular-eslint/template/valid-aria": "error",
  22. e2e Tools DB Systel GmbH | Danny Koppenhagen | 16.01.2024

    36 • Lighthouse-ci • @axe-core/playwright • cypress-axe • jest-axe • pa11y
  23. Storybook DB Systel GmbH | Danny Koppenhagen | 16.01.2024 37

    npx storybook@latest init && npm install @storybook/addon-a11y -D
  24. Slides & Demo DB Systel GmbH | Danny Koppenhagen |

    16.01.2024 39 https://techstories.dbsystel.de/blog/2024/2024-01-16-Accessibility-in-Angular.html
  25. Contact Danny Koppenhagen Platforms for New Mobility (PlaNeMo) [email protected] DB

    Systel GmbH Kynaststr. 1 | 10317 Berlin Thank you for your attention www.dbsystel.de GitHub d-koppenhagen X (Twitter) @d_koppenhagen LinkedIn d-koppenhagen Slides and Source Code