Accessibility (a11y) — làm cho ứng dụng di động có thể sử dụng được cho người khuyết tật. Bao gồm hỗ trợ trình đọc màn hình (VoiceOver trên iOS, TalkBack trên Android), thay đổi kích thước văn bản (Dynamic Type), độ tương phản màu đủ (WCAG 2.1 mức AA), điều hướng không cần thị giác và các thay thế cho cử chỉ. Theo WHO (2023), hơn 1,3 tỷ người (16% dân số) sống với một số dạng khuyết tật — khả năng tiếp cận không phải là tùy chọn mà là điều cần thiết. Tìm hiểu thêm trong tài liệu chính thức của Apple về khả năng tiếp cận.
Những điểm chính
Accessibility (viết tắt a11y — 11 chữ cái giữa «a» và «y») — thực hành phát triển ứng dụng có thể sử dụng được bởi người khiếm thị, khiếm thính, khuyết tật vận động và nhận thức. Trong phát triển di động, khả năng tiếp cận bao gồm bốn kịch bản chính: người dùng mù (trình đọc màn hình), người dùng thị lực kém (thay đổi kích thước, độ tương phản), người dùng điếc và lãng tai (phụ đề, thay thế trực quan cho âm thanh) và người dùng hạn chế vận động (điều khiển bằng giọng nói, Switch Control, vùng chạm lớn).
Yêu cầu pháp lý — ở nhiều quốc gia, khả năng tiếp cận là bắt buộc theo luật. Mỹ: Section 508 và ADA. EU: European Accessibility Act (2025). Vương quốc Anh: Equality Act 2010. Nếu không hỗ trợ khả năng tiếp cận, ứng dụng có thể trở thành mục tiêu của các vụ kiện — tại Mỹ năm 2023, hơn 4.000 vụ kiện đã được nộp về các sản phẩm kỹ thuật số không thể tiếp cận. Apple và Google kiểm tra khả năng tiếp cận trong quá trình kiểm duyệt ứng dụng: App Store Review Guidelines (4.2) và Google Play Store yêu cầu hỗ trợ khả năng tiếp cận tối thiểu.
Lý do kinh doanh — khả năng tiếp cận mở rộng đối tượng người dùng của bạn. Theo Return on Disability (2021), người khuyết tật kiểm soát 13 nghìn tỷ đô la thu nhập khả dụng hàng năm. Các ứng dụng có khả năng tiếp cận cũng xếp hạng tốt hơn trong tìm kiếm (HTML ngữ nghĩa, văn bản thay thế), có xếp hạng người dùng cao hơn và ít đánh giá về vấn đề UX hơn. Tại IT Sectr, chúng tôi đưa khả năng tiếp cận vào định nghĩa hoàn thành của tất cả các dự án — đó là tiêu chuẩn chất lượng, không phải cải tiến tùy chọn.
VoiceOver — trình đọc màn hình của Apple được tích hợp trong iOS, iPadOS và macOS. Người dùng kéo ngón tay trên màn hình, VoiceOver đọc tên thành phần dưới ngón tay. Chạm hai lần để kích hoạt thành phần. VoiceOver hỗ trợ hơn 40 cử chỉ: vuốt ba ngón tay (cuộn), chạm hai lần bằng hai ngón tay (dừng), cử chỉ Z (quay lại). Nhà phát triển kiểm soát nội dung và cách VoiceOver đọc thông qua giao thức UIAccessibility và các thuộc tính accessibilityLabel, accessibilityTraits, accessibilityHint.
class CustomButton: UIButton {
override var isAccessibilityElement: Bool {
get { return true }
set {}
}
// ghi đè accessibilityLabel
override var accessibilityLabel: String? {
get { return "Nút gửi biểu mẫu" }
set {}
}
// ghi đè accessibilityHint
override var accessibilityHint: String? {
get { return "Chạm hai lần để gửi dữ liệu" }
set {}
}
// ghi đè accessibilityTraits
override var accessibilityTraits: UIAccessibilityTraits {
get { return .button }
set {}
}
}
// Dynamic Type — thay đổi kích thước văn bản
titleLabel.font = UIFontMetrics.default.scaledFont(
for: UIFont.systemFont(ofSize: 16)
)
titleLabel.adjustsFontForContentSizeCategory = true
Kiểu chữ động — Dynamic Type trên iOS cho phép người dùng chọn kích thước văn bản (từ XS đến XXXL). Nhà phát triển sử dụng UIFontMetrics.scaledFont để thay đổi kích thước tự động. Văn bản phải hiển thị chính xác ở mọi kích thước: các dòng không được bị cắt, các nút phải phát triển tương ứng với văn bản. UITableView tự động cập nhật chiều cao ô khi kích thước văn bản thay đổi. Bỏ qua Dynamic Type đồng nghĩa với việc làm cho ứng dụng của bạn không thể truy cập được đối với người dùng thị lực kém.
SwiftUI cung cấp các bổ ngữ khả năng tiếp cận: .accessibilityLabel(), .accessibilityHint(), .accessibilityAddTraits(), .accessibilitySortPriority(). Theo mặc định, tất cả các thành phần SwiftUI tiêu chuẩn (Text, Button, Image) đã là thành phần khả năng tiếp cận với nhãn tự động. Đối với Chế độ xem tùy chỉnh, hãy sử dụng .accessibilityElement(children: .combine) để kết hợp các thành phần con thành một. SwiftUI tự động hỗ trợ Dynamic Type và VoiceOver.
VStack {
Image(systemName: "trash")
.accessibilityLabel(Text("Xóa thành phần"))
Text("Thùng rác")
.font(.body)
}
.accessibilityElement(children: .combine)
.accessibilityAddTraits(.isButton)
.accessibilityHint(Text("Xóa vĩnh viễn thành phần đã chọn"))
TalkBack — trình đọc màn hình của Google, được cài đặt sẵn trên hầu hết các thiết bị Android (có sẵn trên Google Play cho tất cả phiên bản Android 5+). TalkBack sử dụng các cử chỉ giống như VoiceOver: vuốt để điều hướng, chạm hai lần để kích hoạt. Nhà phát triển đặt mô tả thành phần thông qua thuộc tính android:contentDescription trong XML hoặc qua setContentDescription() trong mã. Đối với ImageView, contentDescription là bắt buộc — nếu không có, TalkBack sẽ nói «không được gắn nhãn» hoặc đọc tên tệp.
// XML: contentDescription cho ImageView
<ImageView
android:id="@+id/iconDelete"
android:src="@drawable/ic_delete"
android:contentDescription="@string/delete_button_desc"
android:focusable="true"
android:clickable="true" />
// Kotlin: gán theo chương trình
iconDelete.contentDescription = getString(R.string.delete_button_desc)
// Accessibility Delegate (tùy chỉnh)
iconDelete.accessibilityDelegate = object : View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(
host: View, info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.text = "Nút xóa"
info.contentDescription = "Xóa thành phần đã chọn"
info.className = Button::class.java.name
}
}
// Live Regions cho cập nhật động
textView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
Live Regions — cơ chế của Android để thông báo cho TalkBack về các thay đổi nội dung mà không cần tiêu điểm. Thuộc tính android:accessibilityLiveRegion chấp nhận ba giá trị: none (không thông báo), polite (thông báo sau nội dung hiện tại), assertive (thông báo ngay lập tức). Sử dụng polite cho cập nhật trạng thái tải, assertive cho lỗi nghiêm trọng. Lạm dụng assertive sẽ gây hỗn loạn cho người dùng — TalkBack sẽ liên tục làm gián đoạn hành động hiện tại.
Accessibility Scanner — một ứng dụng miễn phí từ Google để kiểm tra khả năng tiếp cận của ứng dụng Android mà không cần truy cập mã nguồn. Trình quét kiểm tra: độ tương phản văn bản, kích thước vùng chạm (tối thiểu 48×48dp theo Nguyên tắc khả năng tiếp cận Android), contentDescription cho ImageView và hệ thống phân cấp thành phần chính xác. Đối với kiểm thử tự động, hãy sử dụng AccessibilityChecks từ Espresso — chúng tích hợp vào CI/CD và kiểm tra khả năng tiếp cận ở mỗi bản dựng.
WCAG 2.1 (Web Content Accessibility Guidelines) — tiêu chuẩn khả năng tiếp cận quốc tế do W3C phát triển. Phiên bản 2.1 (2018) bao gồm 13 tiêu chí bổ sung cho ứng dụng di động. Các mức tuân thủ: A (tối thiểu), AA (bắt buộc đối với hầu hết tổ chức), AAA (tối đa). Apple và Google khuyến nghị mức AA là tối thiểu để xuất bản ứng dụng. WCAG 2.2 được phát hành vào năm 2023 với các cải tiến về tiêu điểm và đầu vào.
Tiêu chí chính cho phát triển di động: độ tương phản văn bản ít nhất 4.5:1 (AA) hoặc 7:1 (AAA), kích thước vùng chạm ít nhất 44×44pt (iOS) hoặc 48×48dp (Android), hỗ trợ cả hướng ngang và dọc mà không mất chức năng, khả năng tắt hoạt ảnh (prefers-reduced-motion), phụ đề cho đa phương tiện và tương thích với điều khiển bằng giọng nói (Voice Control trên iOS, Voice Access trên Android).
| Tiêu chí WCAG 2.1 | Mức | Yêu cầu iOS | Yêu cầu Android |
|---|---|---|---|
| 1.4.3 Độ tương phản (văn bản) | AA | 4.5:1 cho thường, 3:1 cho lớn | 4.5:1 cho thường, 3:1 cho lớn |
| 1.4.11 Độ tương phản (phi văn bản) | AA | 3:1 cho biểu tượng, đường viền | 3:1 cho biểu tượng, đường viền |
| 2.5.5 Kích thước mục tiêu | AAA | 44×44pt | 48×48dp |
| 2.3.3 Hoạt ảnh | AAA | prefers-reduced-motion | android:animateLayoutChanges |
| 4.1.2 Tên, vai trò, giá trị | A | accessibilityLabel, traits | contentDescription, role |
Công cụ kiểm tra độ tương phản — Colour Contrast Analyser (TPGI), WebAIM Contrast Checker, Stark (Figma), Accessibility Inspector (Xcode). Tại IT Sectr, chúng tôi kiểm tra độ tương phản ở giai đoạn thiết kế (Figma + Stark) và một lần nữa ở giai đoạn phát triển (Accessibility Inspector / Accessibility Scanner). Yêu cầu tối thiểu là 4.5:1 cho tất cả văn bản dưới 18pt (14pt in đậm). Logo và các thành phần trang trí không yêu cầu độ tương phản.
Kiểm thử iOS — Accessibility Inspector trong Xcode (Xcode → Open Developer Tool → Accessibility Inspector) kiểm tra nhãn, traits và gợi ý cho từng thành phần. VoiceOver có thể được bật trong Cài đặt hoặc qua Phím tắt khả năng tiếp cận (nhấn ba lần nút). Đối với kiểm thử tự động, hãy sử dụng XCUITest với XCTAssertTrue(app.staticTexts["nhãn"].isAccessibilityElement). Apple khuyến nghị kiểm tra tất cả màn hình ứng dụng khi bật VoiceOver.
Kiểm thử Android — Accessibility Scanner (Play Store) kiểm tra độ tương phản, kích thước vùng chạm và contentDescription. Để tự động hóa: Espresso AccessibilityChecks (nhập: androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.1'). Google khuyến nghị danh sách kiểm tra sau: mọi ImageView đều có contentDescription, vùng chạm ít nhất 48×48dp, văn bản thay đổi kích thước đến 200% mà không bị cắt và tất cả thành phần đều có thể truy cập bằng cách vuốt TalkBack.
Danh sách kiểm tra IT Sectr — trước khi phát hành, chúng tôi xác minh: (1) VoiceOver/TalkBack đọc chính xác tất cả thành phần, (2) văn bản thay đổi kích thước tối đa mà không mất chức năng, (3) tất cả ImageView đều có contentDescription, (4) độ tương phản văn bản ≥4.5:1 trong tất cả chủ đề, (5) vùng chạm ≥44pt/48dp, (6) không có menu ngữ cảnh chỉ khả dụng bằng cách nhấn giữ, (7) hỗ trợ Reduce Motion / Remove Animations trong cài đặt hệ thống. Danh sách kiểm tra này là một phần của định nghĩa hoàn thành cho mỗi sprint.
Các câu hỏi thường gặp
VoiceOver — trình đọc màn hình của Apple cho iOS, iPadOS, macOS. Sử dụng cử chỉ một và nhiều ngón tay (vuốt, chạm hai lần). TalkBack — sản phẩm tương ứng của Google cho Android với cử chỉ tương tự. VoiceOver đọc accessibilityLabel, TalkBack đọc contentDescription. Cả hai đều hỗ trợ màn hình chữ nổi và điều khiển bằng giọng nói. Không có sự khác biệt cơ bản về chức năng.
contentDescription — một thuộc tính View trong Android đặt mô tả văn bản cho TalkBack. Nếu không có, TalkBack nói «không được gắn nhãn» hoặc đọc tên lớp (ImageView, Button). Nó được đặt qua android:contentDescription="@string/desc" trong XML hoặc view.contentDescription = "văn bản" trong mã. Đối với hình ảnh trang trí, hãy sử dụng contentDescription=@null.
Theo WCAG 2.1 mức AA: 4.5:1 cho văn bản thường và 3:1 cho văn bản lớn (từ 18pt hoặc 14pt in đậm). Mức AAA: 7:1 cho thường và 4.5:1 cho lớn. Kiểm tra độ tương phản ở cả hai chủ đề (sáng/tối). Vi phạm độ tương phản là vấn đề khả năng tiếp cận phổ biến nhất trong ứng dụng di động theo Google.
Có, Apple khuyến nghị Dynamic Type cho tất cả ứng dụng. Người dùng đặt kích thước văn bản trong Cài đặt. Nhà phát triển sử dụng UIFontMetrics.scaledFont — phông chữ được thay đổi kích thước tự động. Không có Dynamic Type, người dùng thị lực kém không thể đọc văn bản. iOS tự động kiểm tra Dynamic Type trong quá trình kiểm duyệt App Store.
WCAG (Web Content Accessibility Guidelines) — tiêu chuẩn khả năng tiếp cận nội dung quốc tế từ W3C. Phiên bản 2.1 (2018) bao gồm các tiêu chí cho ứng dụng di động: độ tương phản, kích thước vùng chạm (44×44pt), hỗ trợ trình đọc màn hình, thay thế cử chỉ và phụ đề. Mức AA là tiêu chuẩn tối thiểu để xuất bản trên App Store và Google Play.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm