Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 40 — A11y Annotation in Figma

Đã đọc 0/13 mục · còn khoảng 13 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là designer, vừa hoàn thành một màn hình đăng ký tài khoản đẹp lung linh trong Figma. Màu sắc chuẩn, spacing hoàn hảo, typography tinh tế. Bạn bàn giao file cho developer và nghĩ mọi thứ đã xong. Nhưng đây là câu hỏi: developer sẽ biết được thứ tự đọc của screen reader trên màn hình đó ra sao? Nút "Đăng ký" sẽ có label gì khi người dùng mù chạm vào? Focus sẽ nhảy từ ô email sang ô mật khẩu hay nhảy lung tung? Cái ô "Tôi đồng ý điều khoản" là checkbox thật hay chỉ là một hình vuông trang trí?

Nếu file Figma của bạn không trả lời được những câu hỏi này, thì developer sẽ phải đoán. Và khi họ đoán, họ đoán dựa trên cái nhìn thị giác — thứ mà chính những người khiếm khuyết cần accessibility lại không có được. Kết quả là sản phẩm cuối cùng nhìn thì accessible nhưng thực tế thì không.

Đây chính là khoảng trống mà A11y Annotation (chú thích accessibility) trong Figma lấp đầy. Ở những bài trước, bạn đã học về semantic HTML, ARIA, keyboard navigation, focus order, screen reader. Bài này không dạy lại những khái niệm đó — bài này dạy bạn cách spec (đặc tả) chúng ngay trong file thiết kế, để accessibility trở thành một phần của bản giao việc chứ không phải thứ được nhớ ra sau khi code đã xong. Với designer, đây là kỹ năng biến bạn từ "người vẽ đẹp" thành "người thiết kế trải nghiệm cho tất cả mọi người".

Khái niệm cốt lõi

A11y Annotation là gì?

A11y Annotation là việc bạn thêm các lớp chú thích (thường ở một layer riêng, không xuất hiện trong bản export cuối) lên trên thiết kế Figma để mô tả các thuộc tính accessibility mà mắt thường không nhìn thấy được. Nói cách khác: thiết kế visual trả lời câu hỏi "trông như thế nào", còn annotation trả lời câu hỏi "hoạt động ra sao đối với người dùng công nghệ hỗ trợ".

Có bốn nhóm thông tin cốt lõi mà một annotation tốt cần bao phủ:

1. Semantic roles (vai trò ngữ nghĩa). Phần tử này là gì về mặt ngữ nghĩa? Là heading cấp mấy (h1, h2, h3)? Là button hay link? Là landmark (header, nav, main, footer)? Là list? Một cái hình chữ nhật có chữ bên trong trong Figma có thể là button, link, hoặc chỉ là text tĩnh — chỉ có bạn mới biết ý định thật.

2. Reading order & focus order (thứ tự đọc và thứ tự focus). Screen reader đọc nội dung theo thứ tự nào? Khi người dùng nhấn Tab, focus di chuyển qua các phần tử tương tác theo trình tự nào? Trong Figma, thứ tự layer không nhất thiết trùng với thứ tự đọc mong muốn, nên bạn phải đánh số rõ ràng.

3. Alternative text & labels (văn bản thay thế và nhãn). Ảnh cần alt text gì? Icon-only button (nút chỉ có icon) cần accessible name gì? Ô input cần label gì, kể cả label ẩn về mặt thị giác?

4. States & interactions (trạng thái và tương tác). Component có những trạng thái nào (disabled, selected, expanded/collapsed, error)? Trạng thái đó được thông báo cho screen reader ra sao? Khi mở modal thì focus đi đâu, khi đóng thì focus quay về đâu?

Vì sao không thể để developer tự đoán?

Có một lầm tưởng phổ biến: "Developer giỏi accessibility thì tự họ làm đúng, cần gì designer chú thích". Sai. Developer có thể biết cách triển khai một ARIA attribute, nhưng họ không thể biết ý định thiết kế của bạn. Ví dụ, cùng một cụm ba nút hình tab ở đầu trang — bạn muốn nó là một tablist thực thụ (chuyển tab không load lại trang) hay chỉ là ba link điều hướng? Hai cách này có hành vi keyboard và screen reader hoàn toàn khác nhau (mũi tên trái/phải với tab, Tab với link). Không có annotation, developer sẽ chọn theo cảm tính, và một nửa số lần họ sẽ chọn sai.

Annotation cũng là hợp đồng chất lượng. Khi QA test accessibility, họ cần một cái mốc để so sánh: "Spec nói focus order là 1-2-3, thực tế có đúng không?". Không có annotation, không có gì để kiểm chứng, và accessibility trở thành ý kiến chủ quan thay vì yêu cầu đo được.

Công cụ & plugin

Figma không có annotation accessibility gốc mạnh mẽ, nên cộng đồng đã xây dựng các plugin chuyên dụng. Đáng chú ý nhất:

  • A11y – Focus Order (của cds — CVS Health / hoặc bản của Sara Soueidan phổ biến): vẽ đường nối và đánh số focus order tự động, rất trực quan để thể hiện Tab đi qua đâu.
  • A11y Annotation Kit (thường được nhắc tới nhất, do Indeed Design phát hành mã nguồn mở): một bộ component annotation đầy đủ gồm nhãn cho headings, landmarks, alt text, focus order, form labels, touch target… Bạn kéo thả các component này lên thiết kế như dán sticky note có cấu trúc.
  • Stark: plugin thiên về kiểm tra contrast, mô phỏng color blindness, nhưng phiên bản mới cũng có tính năng annotation và "flows" để mô tả focus order.
  • Include – Accessibility Annotations (của eBay/hoặc Microsoft's tương tự): bộ annotation với các category rõ ràng.
Không có công cụ nào là "chân lý duy nhất". Điều quan trọng là team thống nhất một bộ và dùng nhất quán, để developer đọc file nào cũng hiểu ngay ký hiệu.

Tình huống thực tế

Ví dụ 1 — Sàn thương mại điện tử Việt: nút "yêu thích" biến mất với screen reader

Một startup e-commerce ở TP.HCM (tạm gọi là "ChợXanh") tung ra trang sản phẩm mới. Trên mỗi thẻ sản phẩm có một icon trái tim để thêm vào danh sách yêu thích. Designer vẽ nó rất xinh: một icon trái tim, không có chữ. Developer code đúng như hình: một <button> chứa duy nhất một <svg> trái tim, không có text.

Khi một khách hàng khiếm thị dùng screen reader NVDA lướt qua, họ nghe thấy: "button", "button", "button" — hai mươi cái button giống hệt nhau, không biết cái nào làm gì. Trải nghiệm hoàn toàn vô dụng. Bộ phận CSKH nhận phản hồi, đội dev phải sửa gấp, và cuộc họp "đổ lỗi" giữa design và dev kéo dài cả buổi chiều.

Vấn đề gốc: file Figma không hề chú thích accessible name cho icon button. Nếu designer đã dán một annotation ghi rõ "Icon button — accessible name: 'Thêm [Tên sản phẩm] vào danh sách yêu thích' — aria-pressed thể hiện trạng thái đã thích/chưa thích", developer sẽ triển khai đúng ngay từ đầu.

Bài học: Mọi phần tử tương tác chỉ có icon đều là "mìn accessibility". Icon không có text = screen reader không có gì để đọc. Annotation phải quy định accessible name cho từng cái, và với nút toggle như yêu thích, phải nói rõ trạng thái được thông báo ra sao.

Ví dụ 2 — Ngân hàng số & modal chuyển tiền: focus lạc trôi

Một fintech tại Hà Nội thiết kế luồng chuyển tiền. Khi người dùng nhấn "Xác nhận", một modal hiện lên yêu cầu nhập mã OTP. Designer trong Figma vẽ modal đè lên màn hình, rất đẹp. Nhưng file không có bất kỳ annotation nào về hành vi focus.

Developer, vốn quen làm việc theo hình ảnh, chỉ hiển thị modal bằng cách đặt nó lên trên. Kết quả: khi modal mở, focus của người dùng bàn phím vẫn kẹt ở nút "Xác nhận" phía sau modal. Người dùng nhấn Tab thì focus chạy vòng vòng khắp trang nền đằng sau modal (không bị focus trap), thậm chí bấm được các nút bị modal che khuất. Với một app ngân hàng, đây không chỉ là lỗi accessibility mà còn là lỗ hổng bảo mật và nghiệp vụ.

Sau khi audit, team bổ sung quy trình annotation cho mọi modal. Từ đó, mỗi modal trong Figma đều kèm một khối annotation chuẩn: "Khi mở: focus chuyển tới ô nhập OTP đầu tiên. Focus trap: chỉ di chuyển bên trong modal. Nhấn Esc: đóng modal, focus quay về nút 'Xác nhận'. Role: dialog, aria-modal='true', aria-labelledby trỏ tới tiêu đề modal." Con số cụ thể sau ba tháng: số ticket lỗi accessibility liên quan modal giảm từ 11 xuống 0.

Bài học: Modal, dropdown, và bất kỳ thứ gì "nổi lên" đều cần annotation về vòng đời của focus — mở đi đâu, đóng về đâu, có bị trap không. Đây là thông tin mắt thường không thấy nhưng cực kỳ quan trọng, và nếu designer không spec thì developer gần như chắc chắn bỏ sót.

Ví dụ 3 — Form khảo sát của một tổ chức giáo dục: thứ tự đọc lộn xộn

Một tổ chức edtech ở Singapore làm form khảo sát hai cột: cột trái là câu hỏi tiếng Anh, cột phải là câu hỏi tiếng bản địa. Về mặt thị giác, người dùng đọc theo từng hàng ngang (Anh trái — bản địa phải, rồi xuống hàng). Nhưng trong Figma, thứ tự layer lại là "tất cả cột trái trước, rồi tất cả cột phải". Developer code y hệt thứ tự layer bằng flexbox.

Screen reader đọc toàn bộ câu hỏi tiếng Anh trước, rồi mới đọc toàn bộ câu hỏi bản địa — hoàn toàn mất ngữ cảnh cặp đôi. Người dùng khiếm thị bối rối vì không biết câu bản địa nào ứng với câu Anh nào.

Designer dùng plugin annotation vẽ lại reading order rõ ràng: 1 (Anh) → 2 (bản địa) → 3 (Anh) → 4 (bản địa)… theo đúng logic cặp, đồng thời ghi chú "DOM order phải theo từng cặp, dùng CSS order/grid để bố trí visual hai cột nhưng giữ nguyên thứ tự nguồn". Developer điều chỉnh cấu trúc HTML, giữ visual không đổi mà thứ tự đọc đúng.

Bài học: Thứ tự layer trong Figma ≠ thứ tự đọc mong muốn, đặc biệt trong layout nhiều cột. Reading-order annotation là cách duy nhất để truyền đạt ý định đúng cho developer, tránh việc họ code theo thứ tự layer một cách máy móc.

Hướng dẫn từng bước

Đây là quy trình annotation bạn có thể áp dụng cho bất kỳ màn hình nào.

Bước 1 — Tạo một page hoặc layer annotation riêng. Đừng dán annotation trực tiếp làm bẩn thiết kế visual. Tạo một page tên "A11y Annotations" hoặc một section riêng bên cạnh artboard chính. Nhiều team nhân bản (duplicate) frame gốc rồi annotate lên bản sao, để bản gốc luôn sạch cho việc export.

Bước 2 — Cài plugin annotation. Vào Figma → Plugins → tìm "A11y Annotation Kit" (hoặc bộ mà team bạn thống nhất) và cài. Chạy plugin để nạp thư viện component annotation vào file.

Bước 3 — Đánh dấu heading structure. Rà toàn màn hình, xác định đâu là h1 (thường chỉ một, là tiêu đề chính của trang), rồi h2, h3 theo thứ bậc. Dán nhãn heading level lên từng tiêu đề. Kiểm tra không nhảy cấp (đừng từ h2 nhảy thẳng xuống h4).

Bước 4 — Đánh dấu landmarks. Chỉ ra các vùng cấu trúc: header, nav (điều hướng), main (nội dung chính), aside, footer. Điều này giúp developer biết dùng đúng thẻ semantic và giúp screen reader user nhảy nhanh giữa các vùng.

Bước 5 — Vẽ focus order / reading order. Dùng công cụ focus order của plugin, đánh số 1, 2, 3… cho từng phần tử tương tác theo đúng thứ tự Tab mong muốn. Vẽ đường nối để thấy đường đi của focus. Kiểm tra kỹ ở các layout phức tạp nhiều cột.

Bước 6 — Chú thích từng phần tử tương tác. Với mỗi button, link, input, checkbox: ghi rõ role (button hay link?), accessible name (đặc biệt cho icon-only), và các trạng thái (disabled, selected, expanded, error message).

Bước 7 — Chú thích ảnh và media. Với mỗi ảnh: nó là ảnh thông tin (cần alt text mô tả) hay ảnh trang trí (alt rỗng, alt="")? Viết sẵn nội dung alt text đề xuất — đừng bắt developer tự nghĩ.

Bước 8 — Chú thích component động. Modal, dropdown, accordion, tab: ghi rõ hành vi focus, trạng thái expand/collapse, phím tắt keyboard. Đây là phần dễ sai nhất nên đầu tư kỹ.

Bước 9 — Review cùng developer. Đưa file annotation vào buổi handoff. Đi qua từng annotation, để developer hỏi lại chỗ chưa rõ. Annotation là để đối thoại, không phải để ném qua tường.

Lỗi thường gặp & mẹo

Lỗi 1 — Annotate quá muộn. Nhiều designer đợi đến khi thiết kế "xong 100%" mới annotate, lúc đó phát hiện focus order bất khả thi thì phải làm lại cả layout. Mẹo: nghĩ về accessibility từ khi wireframe, và annotate ngay khi cấu trúc đã ổn định, đừng đợi tới phút chót.

Lỗi 2 — Annotate cho có, thiếu chiều sâu. Ghi "đây là button" thì chưa đủ. Button đó tên gì với screen reader? Có disabled state không? Mẹo: mỗi phần tử tương tác nên trả lời được ba câu — nó là gì (role), tên nó là gì (name), nó có những trạng thái nào (state). Đây chính là mô hình role-name-state mà bạn đã gặp ở bài ARIA.

Lỗi 3 — Làm bẩn file gốc. Annotation dán chồng lên thiết kế làm developer export nhầm cả nhãn. Mẹo: luôn để annotation ở layer/page riêng, ẩn được, và quy ước màu sắc annotation khác biệt hẳn (thường là tím hoặc hồng) để không nhầm với UI.

Lỗi 4 — Dùng thuật ngữ không nhất quán. Team này gọi "focus order", team kia gọi "tab order", người khác gọi "reading order" cho cùng một thứ (thực ra chúng khác nhau tinh tế!). Mẹo: thống nhất một bộ plugin và một glossary thuật ngữ chung cho cả team.

Lỗi 5 — Annotate rồi để đó, không ai đọc. Annotation chỉ có giá trị khi nó là một phần của quy trình handoff và QA. Mẹo: đưa "review annotation" thành một mục bắt buộc trong Definition of Done, và để QA dùng annotation làm checklist kiểm thử.

Mẹo vàng: Bắt đầu nhỏ. Đừng cố annotate toàn bộ design system trong tuần đầu. Chọn một màn hình quan trọng (ví dụ luồng thanh toán), annotate thật kỹ, cho developer dùng thử, thu phản hồi, rồi mới nhân rộng. Accessibility annotation là kỹ năng và văn hóa cần thời gian ngấm.

Bài tập thực hành

Hãy chọn một màn hình quen thuộc — ví dụ trang đăng nhập của một app bạn hay dùng, hoặc tự thiết kế một form đăng ký đơn giản trong Figma gồm: logo, tiêu đề "Đăng ký", ô nhập email, ô nhập mật khẩu (có nút hiện/ẩn mật khẩu dạng icon con mắt), một checkbox "Đồng ý điều khoản", nút "Đăng ký", và một link "Đã có tài khoản? Đăng nhập".

Nhiệm vụ của bạn:

  • Cài plugin A11y Annotation Kit (hoặc tương đương) vào Figma.
  • Tạo một layer annotation riêng, không đè lên thiết kế gốc.
  • Đánh dấu heading structure — đâu là h1?
  • Vẽ focus order từ 1 đến hết. Lưu ý: nút icon con mắt hiện/ẩn mật khẩu có nằm trong focus order không, và nó cần accessible name gì cho hai trạng thái?
  • Chú thích accessible name cho tất cả phần tử tương tác. Đặc biệt xử lý nút con mắt (gợi ý: "Hiện mật khẩu" / "Ẩn mật khẩu").
  • Chú thích checkbox: role là gì, label là gì, và điều gì xảy ra khi chưa tick mà nhấn "Đăng ký" (error state được thông báo ra sao)?
  • Viết alt text đề xuất cho logo (gợi ý: nó là ảnh thông tin hay trang trí trong ngữ cảnh này?).
Sau khi làm xong, hãy thử tưởng tượng bạn là developer chưa từng gặp file này: đọc annotation của bạn, bạn có triển khai được đúng mà không cần hỏi thêm câu nào không? Nếu còn phải đoán chỗ nào, đó chính là chỗ annotation của bạn cần bổ sung.

Tóm tắt

A11y Annotation trong Figma là cầu nối biến ý định accessibility trong đầu designer thành đặc tả rõ ràng cho developer, thay vì để họ đoán mò dựa trên hình ảnh — thứ mà chính người dùng công nghệ hỗ trợ không có được. Bốn nhóm thông tin cốt lõi cần chú thích là: semantic roles (heading, landmark, button vs link), reading/focus order (thứ tự đọc và Tab), alt text & accessible names (đặc biệt cho icon-only), và states & interactions (trạng thái component, hành vi focus của modal/dropdown).

Qua ba tình huống thực tế — nút yêu thích không tên trên sàn e-commerce, modal OTP không trap focus ở app ngân hàng, và form hai cột đọc lộn xộn — bạn thấy rằng lỗi accessibility hầu như luôn bắt nguồn từ một khoảng trống thông tin mà annotation lẽ ra đã lấp đầy. Công cụ thì có A11y Annotation Kit, Stark, Include, focus-order plugin, nhưng quan trọng hơn công cụ là văn hóa: annotate sớm, annotate đủ sâu theo mô hình role-name-state, để ở layer riêng, và biến nó thành một phần bắt buộc của quy trình handoff lẫn QA. Khi bạn làm được điều này, accessibility không còn là thứ sửa chữa sau cùng, mà trở thành một phần được thiết kế có chủ đích ngay từ khâu design — đúng tinh thần inclusive design mà cả khóa học này hướng tới.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi