Xây dựng các ứng dụng Angular dễ tiếp cận hơn

1. Trước khi bắt đầu

biểu trưng Angular màu đen

Hỗ trợ tiếp cận là một phần thiết yếu trong quá trình phát triển web, giúp đảm bảo người dùng có thể nhận biết, hiểu, thao tác và tương tác với ứng dụng. Trên thực tế, cứ 4 người lớn ở Hoa Kỳ thì có 1 người bị khuyết tật ảnh hưởng đến các hoạt động chính trong cuộc sống của họ. Trên toàn thế giới, khoảng 15% dân số thế giới (hơn 1 tỷ người) mắc một dạng khuyết tật nào đó, trong đó khoảng 2 đến 4% phải đối mặt với những khó khăn đáng kể.

Các tình trạng thông thường ảnh hưởng đến việc một người sử dụng web bao gồm khi mù hoặc thị lực kém, khiếm thính hoặc suy giảm thính lực, kỹ năng vận động bị hạn chế, khuyết tật nhận thức và mù màu — và đây chỉ là một danh sách chưa đầy đủ.

Trong khoá học này, a11y là từ viết tắt để chỉ sự hỗ trợ tiếp cận. Lưu ý chữ a đứng trước 11 ký tự và chữ y theo sau.

Để tham khảo hướng dẫn chi tiết về các vấn đề và kỹ thuật thiết kế ứng dụng dễ tiếp cận, hãy xem bài viết Hỗ trợ tiếp cận.

Sản phẩm bạn sẽ tạo ra

  • Sử dụng các phương pháp hay nhất và kỹ thuật tích hợp sẵn để giải quyết các vấn đề thường gặp về khả năng tiếp cận web trong ứng dụng Dumpling Shop Angular minh hoạ
  • Đáp ứng tất cả các nguyên tắc về hỗ trợ tiếp cận, WCAG 2.0 và ARIA 1.2, cũng như vượt qua các bài kiểm tra khả năng hỗ trợ tiếp cận bằng rìu và Lighthouse.

Trang web của cửa hàng Dumpling Time có giao diện hồng và đỏ Trang web của cửa hàng Dumpling Time trong giao diện tím và xanh lục

Kiến thức bạn sẽ học được

Bạn sẽ tìm hiểu 8 vấn đề thường gặp về hỗ trợ tiếp cận trong các ứng dụng Angular ảnh hưởng đến người dùng, cách xác định và khắc phục những vấn đề này. Cụ thể hơn, bạn:

  • Sử dụng Công cụ dành cho nhà phát triển Chrome, Lighthouse và rìu của Google để kiểm tra khả năng hỗ trợ tiếp cận của ứng dụng
  • Giải quyết lỗi ứng dụng trang đơn (SPA) với tiêu đề trang không trùng lặp
  • Khắc phục vấn đề về độ tương phản màu thấp cho người dùng có thị lực kém
  • Sử dụng HTML ngữ nghĩa để đảm bảo trình đọc màn hình điều hướng trang chính xác
  • Dùng Angular Material và các chế độ điều khiển riêng biệt để đảm bảo trình đọc màn hình có thể truy cập vào mọi chế độ điều khiển
  • Thêm tính năng hỗ trợ ARIA cho trình đọc màn hình
  • Nhập và sử dụng gói A11y CDK của Angular
  • Sử dụng FocusTrap để điều hướng trình đọc màn hình thành phần tuỳ chỉnh
  • Báo cáo thông báo với Phát thanh viên của CDK Live
  • Phát hiện người dùng bằng chế độ Độ tương phản cao và triển khai giao diện có độ tương phản cao

Bạn cần có

2. Bắt đầu thiết lập

Lấy

Mọi thứ bạn cần cho dự án này đều nằm trong kho lưu trữ GitHub. Để bắt đầu, hãy sao chép mã và mở mã đó trong môi trường phát triển mà bạn yêu thích.

Nhân bản kho lưu trữ và phân phát ứng dụng

Bạn nên dùng VSCode hoặc IDE cục bộ để thực hiện lớp học lập trình này.

  1. Mở một thẻ trình duyệt mới rồi truy cập https://github.com/googlecodelabs/angular-accessibility.
  2. Phát triển nhánh và sao chép kho lưu trữ và cd angular-accessibility/ vào kho lưu trữ.
  3. Hãy xem nhánh mã khởi đầu git checkout get-started.
  4. Mở mã trong VSCode hoặc IDE mà bạn ưa thích.
  5. Chạy npm install để cài đặt các phần phụ thuộc cần thiết để chạy máy chủ.
  6. Chạy ng serve để chạy máy chủ.
  7. Mở một thẻ trình duyệt truy cập vào http://localhost:4200.

3. Thiết lập đường cơ sở

Điểm xuất phát của bạn là gì?

Điểm xuất phát của bạn là một ứng dụng nhà hàng cơ bản được thiết kế cho lớp học lập trình này. Mã này đã được đơn giản hoá để hiển thị các khái niệm trong lớp học lập trình này và có ít chức năng.

Trang web của cửa hàng Dumpling Time trong giao diện tím và xanh lục

Khám phá bản minh hoạ

Để bắt đầu, hãy tìm hiểu 3 chức năng của ứng dụng:

  1. Sử dụng thanh điều hướng để xem các tuyến đường Cửa hàng của chúng tôi, Câu chuyện của chúng tôiTìm chúng tôi cũng như xem thông tin chi tiết về công ty sản xuất bánh bao.
  2. Thay đổi giao diện để bật/tắt chế độ sáng và tối.
  3. Tuỳ chỉnh số lượng, màu sắc và nhân bánh bao của đơn đặt hàng.
  4. Chọn Mua hàng để ghi đơn đặt hàng tuỳ chỉnh của bạn vào bảng điều khiển.

Sử dụng Angular để giải quyết các vấn đề thường gặp về khả năng tiếp cận web

Trong lớp học lập trình này, bạn sẽ tập trung vào khả năng hỗ trợ tiếp cận của các tính năng hiện có của ứng dụng. Bạn sẽ bắt đầu bằng việc xác định các vấn đề a11y trong ứng dụng của mình, sau đó biến 🛑 thành một ✅ bằng cách triển khai một giải pháp.

Làm cách nào để biết cần khắc phục vấn đề gì?

Bắt đầu từng ví dụ bằng cách nhận diện vấn đề về khả năng hỗ trợ tiếp cận thông qua việc kết hợp kiểm thử thủ công và tự động.

Trong trạng thái hiện tại của web, việc kiểm tra khả năng hỗ trợ tiếp cận theo cách thủ công là bắt buộc.

Bạn có những công cụ có thể xác định các vấn đề về khả năng hỗ trợ tiếp cận, nhưng không công cụ nào có thể chứng nhận rằng một ứng dụng hoàn toàn có thể truy cập được. Kiểm thử thủ công đảm bảo rằng bạn kiểm thử nhiều khái niệm trong ứng dụng a11y, bao gồm thứ tự nội dung logic và tính năng tương đồng.

Kiểm thử thủ công

Để kiểm tra khả năng hỗ trợ tiếp cận trong khoá học này theo cách thủ công, bạn cần bật trình đọc màn hình tích hợp trên máy tính rồi điều hướng qua ứng dụng bằng thao tác trên bàn phím. Để biết thêm thông tin, hãy xem phần Ngữ nghĩa và trình đọc màn hình.

Thực hành bằng cách bật trình đọc màn hình và thao tác trên màn hình.

Bạn có thể sử dụng VoiceOver tích hợp sẵn trong MacOS. Nhấp vào System Preferences (Lựa chọn ưu tiên về hệ thống) > Hỗ trợ tiếp cận > VoiceOver > Bật VoiceOver để bật. Để bật/tắt VoiceOver, hãy nhấn nhanh TouchID 3 lần trong khi giữ phím Command.

Trong khoá học này, bạn chủ yếu kiểm tra các vấn đề theo cách thủ công và sử dụng các công cụ tự động để hỗ trợ kiểm tra các tính năng tự động cụ thể.

Kiểm thử tự động

Bạn cũng sử dụng một vài công cụ phát triển để tự động hoá và kiểm tra ứng dụng của mình. Những công cụ này cho phép bạn kiểm tra những nội dung như có văn bản thay thế trên hình ảnh hay tỷ lệ tương phản của màu văn bản. Bạn có thể xem những công cụ này là công cụ tìm lỗi mã nguồn; trẻ có thể nhận ra văn bản thay thế đang xuất hiện, nhưng bạn phải tự kiểm tra xem nội dung có hợp lý và có giá trị không.

Lighthouse và Công cụ cho nhà phát triển Chrome

  1. Mở Công cụ cho nhà phát triển Chrome.
  2. Chọn thẻ Lighthouse rồi chọn hộp đánh dấu Hỗ trợ tiếp cận.
  3. Nhấp vào Tạo báo cáo để chạy quy trình kiểm tra a11y Lighthouse.

Thẻ ví dụ về Lighthouse có nút Tạo báo cáo trong thẻ Công cụ của Chrome cho nhà phát triển

Rìu

  1. Cài đặt tiện ích Công cụ cho nhà phát triển rìu. Bạn có thể phải khởi động lại trình duyệt để xem tiện ích này.
  2. Mở Công cụ cho nhà phát triển Chrome.
  3. Chọn thẻ Công cụ cho nhà phát triển rìu và chọn Quét tất cả trang của tôi để chạy quy trình quét rìu Công cụ cho nhà phát triển.

Tìm lỗi mã nguồn

Bạn có thể sử dụng các quy tắc ESLint của Angular để tìm lỗi mã nguồn cho các thuộc tính a11y có thể tự động hoàn thành.

Trong eslint.json, hãy thêm các nội dung sau đây cho khả năng hỗ trợ tiếp cận:

"@angular-eslint/template/accessibility-alt-text": 2,
"@angular-eslint/template/accessibility-elements-content": 2,
"@angular-eslint/template/accessibility-label-for": 2,
"@angular-eslint/template/no-positive-tabindex": 2,
"@angular-eslint/template/accessibility-table-scope": 2,
"@angular-eslint/template/accessibility-valid-aria": 2,
"@angular-eslint/template/click-events-have-key-events": 2,
"@angular-eslint/template/mouse-events-have-key-events": 2,
"@angular-eslint/template/no-autofocus": 2,
"@angular-eslint/template/no-distracting-elements": 2

Để biết thêm thông tin, hãy xem các quy tắc ESLint mới nhất trên GitHub.

Điểm xuất phát của bạn

Khi sử dụng các phương pháp kiểm thử mới, bạn có thể xác định các vấn đề sau trong ứng dụng của mình bằng tính năng kiểm tra bằng Lighthouse và rìu, cũng như VoiceOver thủ công:

Kiểm tra Lighthouse của Chrome cho nhà phát triển với điểm số là 82

Kiểm tra khả năng hỗ trợ tiếp cận:

  • 🛑 Tất cả các trang đều có cùng tiêu đề trang
  • 🛑 Các phần tử phải có độ tương phản màu phù hợp
  • 🛑 HTML phải có thứ tự, tên và vai trò hợp lý
  • 🛑 Không chọn được hộp đánh dấu lồng nhau cho trình đọc màn hình
  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

4. Xác định tiêu đề trang riêng biệt

Việc cung cấp tiêu đề trang độc đáo, súc tích giúp người dùng sử dụng các dịch vụ của a11y nhanh chóng hiểu được nội dung và mục đích của trang web. Tiêu đề trang rất quan trọng đối với người dùng khiếm thị vì đó là phần tử trang đầu tiên được phần mềm đọc màn hình công bố.

Angular là ứng dụng trang đơn và do đó, phần lớn các quá trình chuyển đổi, chẳng hạn như chuyển sang một trang mới, không liên quan đến việc tải lại một trang. Cho đến nay, điều này có nghĩa là mỗi trang có tiêu đề trang giống hệt nhau và không giúp bạn hiểu được nội dung hoặc mục đích của trang đó.

Trong Angular phiên bản 14, Bộ định tuyến đã thêm một phương thức tích hợp sẵn để xác định tiêu đề trang duy nhất ngay từ đầu. Điều này mang đến một cách tiếp cận đơn giản để đảm bảo nhà phát triển tuân theo các phương pháp hay nhất về tiêu đề trang.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Tất cả các trang đều có cùng tiêu đề trang

Bạn có thể tìm thấy từng bước này dưới phần nhận xét: TODO: #4. Define unique page titles.

Xác định vấn đề

Để xác định vấn đề này, hãy bật trình đọc màn hình rồi di chuyển giữa các thẻ Cửa hàng của chúng tôi, Câu chuyện của chúng tôiTìm chúng tôi để xem các tiêu đề trang:

  1. Bật VoiceOver.
  2. Sử dụng tính năng điều hướng bằng thẻ để điều hướng giữa các trang.
  3. Xác minh rằng tiêu đề trang luôn là a11y trong Angular.

Đây là một vấn đề vì tiêu đề trang phải là duy nhất để người dùng có thể nhanh chóng hiểu nội dung trên trang mà không cần phải di chuyển qua đó.

Trình duyệt Chrome có 3 thẻ đang mở có tiêu đề trang giống nhau: "a11y ở Angular"

Thêm tiêu đề trang có ý nghĩa

Nếu một trang hoặc chế độ xem thay đổi, bạn nên quản lý tiêu đề trang đúng cách. Để khắc phục vấn đề này, bạn sử dụng thuộc tính Router.title tích hợp sẵn trong Angular để xác định tiêu đề riêng biệt cho từng trang của mình.

  1. Thêm tiêu đề duy nhất cho mỗi tuyến trong số 3 tuyến đã xác định:

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, title: 'Our Shop – a11y in Angular' },
  { path: 'about', component: AboutComponent, title: 'Our Story - a11y in Angular' },
  { path: 'locate', component: LocationComponent, title: 'Find Us - a11y in Angular' },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];

Thao tác này sẽ tự động nhập và sử dụng Router's Title Service nâng cao để quản lý việc thay đổi tiêu đề trang trên điều hướng cho phù hợp với thuộc tính tiêu đề được xác định trong các tuyến của chúng tôi. Bạn cũng có thể quản lý những tiêu đề trang phức tạp hơn bằng TitleStrategy tuỳ chỉnh.

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. Giờ đây, các trang này sẽ có tiêu đề riêng biệt!

Trình duyệt Chrome có ba thẻ đang mở với tiêu đề trang độc đáo: "Cửa hàng của chúng tôi – a11y ở Angular", "Câu chuyện của chúng ta – a11y trong Angular", "Tìm chúng tôi – a11y trong Angular"

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • 🛑 Các phần tử phải có độ tương phản màu phù hợp
  • 🛑 HTML phải có thứ tự, tên và vai trò hợp lý
  • 🛑 Không chọn được hộp đánh dấu lồng nhau cho trình đọc màn hình
  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

5. Đảm bảo độ tương phản màu phù hợp

Thiết kế của bạn trông có vẻ thú vị nhưng sẽ không hiệu quả nếu những người bị suy giảm thị lực như mù màu không đọc được nội dung của bạn. Nguyên tắc hỗ trợ tiếp cận nội dung web (WCAG 2.0) xác định một loạt tỷ lệ tương phản màu sắc để đảm bảo người dùng tiếp cận được nội dung. Trong Angular và trên web, bạn có thể xác định các bảng màu nhằm đảm bảo các thành phần của bạn đáp ứng các tiêu chuẩn này và người dùng có thị lực kém và người bị mù màu đều có thể nhìn thấy các bảng màu.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Các phần tử phải có độ tương phản màu phù hợp

Bạn có thể xem từng bước này trong phần bình luận: TODO: #5. Ensure adequate color contrast.

Sử dụng Công cụ cho nhà phát triển Chrome để xác định các vấn đề về độ tương phản thấp

Để xác định vấn đề này, hãy sử dụng Công cụ cho nhà phát triển Chrome để kiểm tra các phần tử trong ứng dụng của bạn.

  1. Dùng công cụ kiểm tra để xem các nút biểu tượng trình đơn. Bạn có thể thấy độ tương phản là 1,85, thấp hơn nhiều so với các yêu cầu của WCAG.

Công cụ của Chrome cho nhà phát triển kiểm tra phần tử của nút Trang chủ có độ tương phản thấp

  1. Hãy chạy quy trình kiểm tra Khả năng hỗ trợ tiếp cận trong Lighthouse hoặc quét của rìu để xem các vấn đề về tỷ lệ tương phản.

Kết quả kiểm tra Lighthouse của Chrome cho nhà phát triển với lỗi: "Màu nền và nền trước không có đủ tỷ lệ tương phản"

Thay đổi màu giao diện Material

Bảng phối màu của thành phần được xác định trong giao diện Material tuỳ chỉnh. Bạn cập nhật giá trị giao diện của mình để đáp ứng nguyên tắc về tỷ lệ tương phản màu.

Cập nhật giao diện Material để sử dụng màu văn bản tối hơn, tăng tỷ lệ tương phản của các biểu tượng:

src/styles.scss

$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);

Bạn cũng có thể sử dụng công cụ hỗ trợ tiếp cận tích hợp sẵn trong Công cụ dành cho nhà phát triển Chrome để tìm màu đáp ứng tiêu chuẩn hoặc cập nhật các giá trị màu riêng lẻ trong Sass.

Xác minh các thay đổi

Kiểm tra lại các phần tử và xác minh các thay đổi của bạn, giao diện của chúng ta hiện đã có đủ tỷ lệ tương phản màu!

Công cụ của Chrome cho nhà phát triển kiểm tra phần tử của nút Trang chủ có đủ độ tương phản

Kiểm tra khả năng hỗ trợ tiếp cận

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • 🛑 HTML phải có thứ tự, tên và vai trò hợp lý
  • 🛑 Không chọn được hộp đánh dấu lồng nhau cho trình đọc màn hình
  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

6. Sử dụng HTML ngữ nghĩa

Các phần tử HTML gốc nắm bắt một số mẫu tương tác chuẩn quan trọng đối với khả năng tiếp cận. Mặc dù đoạn có thể được tạo kiểu dưới dạng span và div có thể được tạo kiểu dưới dạng nút, nhưng phần tử HTML ngữ nghĩa đảm bảo rằng trình đọc màn hình và thao tác bằng bàn phím hiểu được các hoạt động tương tác và điều khiển HTML của bạn.

Khi tạo các thành phần Angular, bạn nên trực tiếp sử dụng lại các thành phần gốc này nếu có thể, thay vì triển khai lại các hành vi được hỗ trợ. Điều này đảm bảo rằng trang có cấu trúc nội dung và luồng nội dung tự nhiên tốt, đồng thời thẻ được sắp xếp theo thứ tự hợp lý để hỗ trợ người dùng điều hướng trang web bằng cách sử dụng bàn phím hiệu quả.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 HTML phải có thứ tự, tên và vai trò hợp lý

Bạn có thể xem từng bước này trong phần bình luận: TODO: #6. Use Semantic HTML.

Xác định vấn đề

  1. Bật VoiceOver.
  2. Sử dụng thao tác di chuyển bằng thẻ để nhấp đến thẻ Câu chuyện của chúng tôi.
  3. Lưu ý rằng thứ tự nhấn phím tab không theo tuần tự.
  4. Nhấp vào Mua.
  5. Lưu ý rằng nút này không được nhận dạng là một nút.

Kết quả kiểm tra lỗi Ngọn hải đăng công cụ của Chrome cho nhà phát triển: Các phần tử tiêu đề không theo thứ tự giảm dần theo tuần tự, tiêu đề được sắp xếp đúng cách mà không bỏ qua các cấp độ truyền tải cấu trúc ngữ nghĩa của trang, giúp bạn dễ dàng điều hướng và hiểu rõ hơn khi sử dụng công nghệ hỗ trợ. Tìm hiểu thêm.

Thay đổi <div> vào một <button>

Thay thế <div> tuỳ chỉnh bằng nút Material:

src/app/shop/shop.component.html

<button mat-flat-button 
  color="primary" 
  class="purchase-button"
  (click)="fauxPurchase()">
  Purchase
</button>

Sử dụng các phần tử tiêu đề theo tuần tự

Sắp xếp lại văn bản để sử dụng HTML ngữ nghĩa và áp dụng kiểu bằng kiểu chữ Angular Material:

src/app/about/about.component.html

<h2>Who are we?</h2>
<p class="mat-subheading-2">Have you ever thought, "wow, I love dumplings"?</p>
<p class="right mat-subheading-1">Who hasn't.</p>
<p class="center mat-subheading-1">We took it one step further and created Dumpling Dumpling,</p> 
<p class="center mat-subheading-1">double the dumpling, double the fun.</p>
<div class="spacer"></div>
<h2>How are we different?</h2>
<p class="mat-subheading-2">Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</p>
<p class="right mat-subheading-2">This shop is concept only.</p>

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. VoiceOver hiện nhận ra nút và văn bản được đọc theo thứ tự logic!

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • 🛑 Không chọn được hộp đánh dấu lồng nhau cho trình đọc màn hình
  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

7. Tạo các thành phần điều khiển có thể chọn bằng Angular Material

Một mẫu tương tác phức tạp dành cho các dịch vụ hỗ trợ tiếp cận là các chế độ điều khiển lồng nhau. Hãy suy nghĩ về các mục con trong trình đơn hoặc hộp đánh dấu lồng nhau. Làm cách nào để bạn cho người dùng biết rằng bạn có thể chọn một nhóm con gồm các lựa chọn hoặc chuyển đến một mục trong trình đơn chính?

Trong Angular, hãy đơn giản hoá các trình đơn và chức năng điều khiển để tạo các thành phần có thể điều hướng bằng cách đơn giản hoá các thành phần điều khiển nhiều nhất có thể. Trong ví dụ này, bạn sử dụng hộp danh sách của Angular Material để tạo một ví dụ về mẫu tương tác này.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Không chọn được hộp đánh dấu lồng nhau cho trình đọc màn hình

Bạn có thể xem từng bước này trong phần bình luận: TODO: #7. Create selectable controls with Angular Material.

Xác định vấn đề

Để xác định sự cố này, chúng ta sẽ bật trình đọc màn hình và thử chọn một hộp kiểm lồng nhau.

  1. Bật VoiceOver.
  2. Hãy chọn các hương vị nhân khác nhau.
  3. Lưu ý rằng các hộp đánh dấu cấp độ gốc không chỉ định phần tử con khi được đọc bằng VoiceOver. Làm cách nào để biết hộp đánh dấu Vegan bị bỏ chọn sau khi bạn bỏ chọn hộp đánh dấu Bok Choy?

Trình đơn hộp đánh dấu có các lựa chọn: Fillings Vegan Bok Choy Tofu & Thịt gà không thể lấy thịt

A11y trong Material

Bạn sẽ thay thế hộp đánh dấu ngữ nghĩa bằng hộp đánh dấu Angular Material, vốn có sẵn kiến thức về mẫu tương tác này. Điều quan trọng cần lưu ý là việc thay thế các thành phần bằng Material không đảm bảo khả năng hỗ trợ tiếp cận. Giống như mọi thành phần khác, bạn cần kiểm thử theo cách thủ công vì có rất nhiều cách triển khai Material mà không thể truy cập được.

Thay thế hộp đánh dấu bằng hộp đánh dấu Material

  1. Trước tiên, hãy thêm danh sách nhân mới và một biến để lưu trữ các hương vị nhân đã chọn:

src/app/shop/shop.component.ts

@Component(...)
export class ShopComponent implements OnInit {
  fillings: string[] = ['Bok Choy & Chili Crunch', 'Tofu & Mushroom', 'Chicken & Ginger', 'Impossible Meat & Spinach'];
  selectedFillings: string[] = [];

  fauxPurchase(): void {
    let flavor = '';
    this.selectedFillings.forEach(filling => {
      flavor = flavor + " " + filling
    })
  }
}
  1. Thêm <mat-selection-list> để thay thế nhóm hộp kiểm HTML lộn xộn này:

src/app/shop/shop.component.html

<mat-selection-list [(ngModel)]="selectedFillings" 
  aria-label="Dumpling fillings">
  <mat-list-option *ngFor="let flavor of fillings" 
    [value]="flavor" 
    color="primary">
    {{ flavor }}
  </mat-list-option>
</mat-selection-list>

Các bình luận trên TODO cũng cho biết vị trí bạn có thể xoá một số Sass không dùng đến trong src/app/shop/shop.component.scss để dọn dẹp kiểu.

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. Giờ đây, bạn có thể chọn các hộp đánh dấu và di chuyển trực quan hơn nhờ trình đọc màn hình!

Trình đơn hộp đánh dấu có các mục: Fillings Bok Choy & Đậu phụ giòn ớt và Món gà nấm và Thịt không thể làm từ gừng Số lượng rau chân vịt

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • Trình đọc màn hình có thể truy cập vào tất cả các chế độ điều khiển
  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

8. Cung cấp nhãn kiểm soát bằng ARIA

Bạn đã sửa đổi các thành phần HTML ngữ nghĩa và Material của ứng dụng Angular. Tuy nhiên, một số thành phần đòi hỏi các thuộc tính cụ thể để trình đọc màn hình điều hướng đầy đủ.

Thông số kỹ thuật về Ứng dụng Internet đa dạng thức có thể hỗ trợ tiếp cận của Sáng kiến hỗ trợ tiếp cận web (WAI-ARIA hoặc ARIA) giúp làm cầu nối các vấn đề không thể quản lý bằng HTML gốc. Tệp này cho phép bạn chỉ định các thuộc tính sửa đổi cách dịch một phần tử sang cây hỗ trợ tiếp cận.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Trình đọc màn hình không đọc giá trị của thanh trượt

Bạn có thể xem từng bước này trong phần bình luận: TODO: #8. Provide control labels with ARIA.

Xác định vấn đề

Để xác định sự cố này, hãy bật trình đọc màn hình và di chuyển thanh trượt của bạn:

  1. Bật VoiceOver.
  2. Chuyển đến thanh trượt số lượng rồi thay đổi giá trị.
  3. Lưu ý rằng nhãn giá trị bị thiếu.

Lỗi kết quả kiểm tra Lighthouse của Chrome Công cụ cho nhà phát triển:  Các trường nhập dữ liệu ARIA không có tên thành phần hỗ trợ tiếp cận. Khi một trường nhập không có tên thành phần hỗ trợ tiếp cận, trình đọc màn hình sẽ thông báo trường đó bằng tên chung, khiến người dùng trình đọc màn hình không dùng được trường đó. Tìm hiểu thêm.

Sử dụng các thuộc tính ARIA

Kiểm soát nhãn bằng cách sử dụng từ aria-label đến <mat-slider>:

src/app/shop/shop.component.html

<mat-slider
  aria-label="Dumpling order quantity slider"
  id="quantity"
  name="quantity"
  color="primary"
  class="quantity-slider"
  [max]="13"
  [min]="1"
  [step]="1"
  [tickInterval]="1"
  thumbLabel
  [(ngModel)]="quantity">
</mat-slider>

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. Bây giờ, bạn có thể di chuyển thanh trượt!

Kiểm tra Lighthouse của Chrome Công cụ cho nhà phát triển với quá trình kiểm tra vượt qua các chế độ kiểm soát ARIA của trình đọc màn hình.

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • Trình đọc màn hình có thể truy cập vào tất cả các chế độ điều khiển
  • Thanh trượt sử dụng các thuộc tính ARIA để cung cấp nhãn
  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

9. Thêm sức mạnh của @angular/cdk/a11y

Cho đến nay, bạn đã sử dụng công cụ Angular tích hợp sẵn để khắc phục các vấn đề thường gặp liên quan đến a11y. Bây giờ, hãy cùng tìm hiểu mô-đun a11y của CDK và cách mô-đun này có thể giúp chúng ta giải quyết các vấn đề phức tạp và cụ thể về Angular.

Khi kết thúc phần này, bạn sẽ tiếp tục khoá học này bằng công cụ mô-đun A11y của Angular.

Bạn có thể xem các bước này dưới phần bình luận: TODO: #9. Add the power of @angular/cdk/a11y.

Nhập mô-đun

Thêm mô-đun vào ứng dụng:

src/app/app.module.ts

import { A11yModule } from '@angular/cdk/a11y';

@NgModule({
  declarations: [...],
  imports: [
    A11yModule
  ],
  providers: [...],
  bootstrap: [...]
})

'@angular/cdk/a11y' có thể làm gì?

Mô-đun a11y cung cấp một số công cụ để cải thiện khả năng tiếp cận và đặc biệt hữu ích cho các tác giả thành phần.

Trong các phần sau, bạn sẽ thêm ba dịch vụ phổ biến: FocusTrap, LiveReleaser và HighCounter (Độ tương phản).

Để biết thêm thông tin về tất cả dịch vụ khác mà @angular/cdk/a11y cung cấp, hãy xem bài viết Hỗ trợ tiếp cận.

10. Kiểm soát tiêu điểm bằng FocusTrap

Khi một hộp thoại hoặc cửa sổ phụ mở, người dùng chỉ tương tác bên trong hộp thoại hoặc cửa sổ đó. Việc cho phép tiêu điểm thoát ra bên ngoài hộp thoại sẽ kết hợp các ngữ cảnh và tạo trạng thái mà người dùng không biết họ đang ở đâu trên trang.

Trong Angular, lệnh cdkTrapFocus sẽ bẫy tiêu điểm khoá tab- trong một phần tử. Thư viện này dùng để tạo trải nghiệm dễ tiếp cận cho các thành phần như hộp thoại phương thức, trong đó phải hạn chế tiêu điểm.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Tiêu điểm của trình đọc màn hình trong công cụ chọn màu sẽ thoát khỏi hộp thoại

Bạn có thể xem các bước này trong phần bình luận: TODO: #10. Control focus with FocusTrap.

Xác định vấn đề

Để xác định sự cố này, hãy bật trình đọc màn hình rồi mở hộp thoại công cụ chọn màu.

  1. Bật VoiceOver.
  2. Sử dụng tính năng điều hướng bằng phím tab để thay đổi màu.
  3. Kiểm tra để xem thứ tự lấy nét trực quan và bẫy lấy nét trong công cụ chọn màu.

Trang web của cửa hàng Dumpling Time có giao diện tím và xanh lục với hộp thoại đang mở để chọn màu gói bánh bao

Thêm FocusTrap

Bạn có thể dùng cdkFocusTrap để giữ và kiểm soát thứ tự lấy nét trong các thành phần tuỳ chỉnh. Chỉ cần sử dụng mat-dialog-content là đủ để giải quyết hầu hết vấn đề bằng cách giữ lại tiêu điểm trong hộp thoại. Thêm thuộc tính cdkFocusInitial để xác định vùng tiêu điểm ban đầu trên màu của trình bao bọc bánh bao <mat-selection-list> trong hộp thoại công cụ chọn màu.

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.html

<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false" cdkFocusInitial>
  ...
</mat-selection-list>

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. Ban đầu, tiêu điểm được đặt ở tuỳ chọn Change Color (Thay đổi màu) trong hộp thoại!

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • Trình đọc màn hình có thể truy cập vào tất cả các chế độ điều khiển
  • Thanh trượt sử dụng các thuộc tính ARIA để cung cấp nhãn
  • Công cụ chọn màu có tính năng bẫy lấy nét chính xác
  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

11. Thông báo về những thay đổi với Phát thanh viên trực tiếp

Trình đọc màn hình cần được thông báo khi có nội dung nào đó trên trang thay đổi. Hãy tưởng tượng bạn đang tìm cách gửi biểu mẫu hoặc hoàn tất giao dịch mua, nhưng không biết rằng có một lỗi đã xảy ra ngăn cản việc gửi biểu mẫu. Điều đó rất khó chịu!

Phát thanh viên được dùng để thông báo tin nhắn cho người dùng trình đọc màn hình thông qua một khu vực phát trực tiếp aria để đảm bảo trình đọc màn hình được thông báo về thông báo và những thay đổi trên trang trực tiếp. Để biết thêm thông tin về các khu vực phát trực tiếp aria, hãy xem WAI-ARIA của W3C. Trong Angular, việc gọi LiveReportingr dưới dạng một dịch vụ là một giải pháp dễ thử nghiệm hơn so với các thuộc tính aria-live.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Các thay đổi, lỗi và thông báo không có thông báo

Bạn có thể xem các bước này trong phần bình luận: TODO: #11. Announce changes with LiveAnnouncer.

Xác định vấn đề

Để xác định vấn đề này, hãy bật trình đọc màn hình và chọn Mua mà không cần hoàn tất các trường trong biểu mẫu:

  1. Bật VoiceOver.
  2. Hãy dùng tính năng điều hướng bằng thẻ để thay đổi màu sắc và thực hiện giao dịch mua giả mạo.
  3. Lưu ý rằng không có chỉ báo màu nào được chọn khi thoát khỏi hộp thoại và giao dịch mua chưa được đọc.

Trang web của cửa hàng Dumpling Time có giao diện hồng và đỏ với hộp thoại đang mở để chọn màu gói bánh bao

Thêm LiveReleaser vào đoạn mã của bạn

Thêm LiveReleaser rồi thông báo cả việc lựa chọn màu sắc lẫn giao dịch mua giả mạo dưới dạng một chuỗi. Trong khi triển khai thực tế, thông tin này có thể được đọc khi bạn chuyển đến một hệ thống thanh toán của bên thứ ba hoặc khi gặp lỗi biểu mẫu.

  1. Thêm thông báo khi màu được chọn:

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ColorPickerDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ColorPickerDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ColorDialogData,
    private liveAnnouncer: LiveAnnouncer) { }

  public changeColor(color: string): void {
    this.liveAnnouncer.announce(`Select color: ${color}`);
    this.dialogRef.close();
  }
}
  1. Thêm thông báo khi thực hiện giao dịch mua giả mạo:

src/app/shop/shop.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ShopComponent implements OnInit {

  constructor(private liveAnnouncer: LiveAnnouncer) { }

  fauxPurchase(): void {
    let flavor = '...';
    const fakePurchase = `Purchase ${this.quantity} ${flavor}dumplings in the color ${this.color}!`;

    this.liveAnnouncer.announce(fakePurchase);
  }
}

Xác minh các thay đổi

Bật lại trình đọc màn hình và xác minh nội dung thay đổi. Giờ bạn đã được thông báo về lỗi!

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • Trình đọc màn hình có thể truy cập vào tất cả các chế độ điều khiển
  • Thanh trượt sử dụng các thuộc tính ARIA để cung cấp nhãn
  • Công cụ chọn màu có tính năng bẫy lấy nét chính xác
  • Thông báo về những thay đổi, lỗi và thông báo
  • 🛑 Chế độ Tương phản cao chưa bật

12. Bật chế độ Tương phản cao

Microsoft Windows hỗ trợ tính năng hỗ trợ tiếp cận có tên là Chế độ tương phản cao. Chế độ này thay đổi giao diện của tất cả ứng dụng, bao gồm cả ứng dụng web, để tăng độ tương phản đáng kể. Trong Angular, bạn muốn tôn trọng lựa chọn ưu tiên của người dùng trong ứng dụng của mình.

HighContrastModeDetector cho phép bạn xác định xem trình duyệt hiện có đang ở trong môi trường chế độ tương phản cao hay không.

Internet Explorer, Microsoft Edge và Firefox đều hỗ trợ chế độ này. Google Chrome không hỗ trợ Chế độ tương phản cao của Windows. Dịch vụ này không phát hiện được chế độ tương phản cao do tiện ích trình duyệt Chrome có độ tương phản cao thêm vào.

Khi kết thúc phần này, ứng dụng của bạn sẽ vượt qua quy trình kiểm tra sau đây:

  • 🛑 Chế độ Tương phản cao chưa bật

Bạn có thể xem các bước này trong phần bình luận: TODO: #12. Enable HighContrast mode.

Xác định vấn đề

Để xác định sự cố này, hãy mở ứng dụng của bạn trong Internet Explorer, Microsoft Edge hoặc Firefox, bật Chế độ tương phản cao và quan sát thấy không có thay đổi nào:

  1. Mở ứng dụng của bạn trong Internet Explorer, Microsoft Edge hoặc Firefox.
  2. Bật Chế độ tương phản cao.
  3. Lưu ý rằng ứng dụng không thay đổi.

Thêm tính năng hỗ trợ cho chế độ tương phản cao

Trong styles.scss, hãy sử dụng danh sách kết hợp cdk-high-contrast có trong @angular/cdk/a11y để thêm đường viền vào các nút ở chế độ Độ tương phản cao:

src/app/shop/shop.component.scss

@use '@angular/cdk';

.purchase-button {
    border-radius: 5px;
    background-color: mat.get-color-from-palette(mat.$pink-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$pink-palette, 50);
    }
}

:host-context(.dark-theme) {
  .purchase-button {
    background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$light-green-palette, 50);
    }
  }
}

Xác minh các thay đổi

Làm mới ứng dụng và xác minh các thay đổi. Bạn đã thêm đường viền vào nút ở chế độ Độ tương phản cao!

Trang web của cửa hàng Dumpling Time có giao diện đỏ và hồng, trong đó Chế độ tương phản cao đang bật và nút mua hàng hiện được làm nổi bật với đường viền màu đỏ đậm Trang web của cửa hàng Dumpling Time có giao diện màu xanh dương và xanh lục, trong đó Chế độ tương phản cao đang bật và nút mua hàng hiện được làm nổi bật với đường viền màu xanh dương đậm

Kiểm tra khả năng hỗ trợ tiếp cận:

  • Tất cả các trang đều có tiêu đề trang riêng biệt
  • Màu sắc có tỷ lệ tương phản đủ
  • HTML ngữ nghĩa đảm bảo tương tác logic
  • Trình đọc màn hình có thể truy cập vào tất cả các chế độ điều khiển
  • Thanh trượt sử dụng các thuộc tính ARIA để cung cấp nhãn
  • Công cụ chọn màu có tính năng bẫy lấy nét chính xác
  • Thông báo về những thay đổi, lỗi và thông báo
  • Đã bật chế độ tương phản cao

13. Xin chúc mừng!

Xin chúc mừng! Bạn đã giải quyết xong các vấn đề thường gặp về khả năng hỗ trợ tiếp cận web trong ứng dụng Angular! 🎉

Để xem tất cả các giải pháp, hãy xem nhánh main.

Trang web của cửa hàng Dumpling Time có giao diện đỏ và hồng cho thấy tất cả thay đổi đã thực hiện trong lớp học lập trình này Trang web của cửa hàng Dumpling Time có giao diện màu xanh dương và xanh lục cho thấy tất cả thay đổi trong lớp học lập trình này Kiểm tra Lighthouse của Chrome cho nhà phát triển với điểm số 100/100

Giờ đây, bạn đã biết các bước chính cần thiết để giải quyết 8 lỗi thường gặp trong ứng dụng Angular.

Tìm hiểu thêm

Hãy tham khảo các lớp học lập trình sau:

Đọc các tài liệu này: