← Lập trình với Claude Code

Bài 16 · Nâng cao · 24 phút· Cập nhật 11/06/2026

Chuẩn nghề: Clean code & WCAG

Biên soạn bởi Nguyễn Anh Tuấn

Đóng gói clean code & WCAG thành Skill review + hook tự format/lint, để Claude giữ code sạch và giao diện ai cũng dùng được.

Bài trước lo code đúng & an toàn. Bài này lo hai chuẩn nữa của senior: clean code (để cả nhóm - và Claude ở phiên sau - đọc & sửa nhanh) và khả năng truy cập (để sản phẩm dùng được cho MỌI người). Cả hai đều mã hoá được thành Skill + hook để Claude áp dụng mặc định.

  • Clean code: tốc độ bảo trì tương lai - quan trọng gấp đôi khi làm cùng AI.
  • Accessibility (a11y): người dùng thật + thường là yêu cầu pháp lý.
  • Mã hoá: Skill review + hook tự format/lint + luật CLAUDE.md ngắn.

Gói tiêu chí clean code thành một Skill để Claude tự soi (và bạn gọi tay khi cần):

.claude/skills/clean-code-review/SKILL.md

---
name: clean-code-review
description: Review code về độ sạch & dễ bảo trì. Dùng khi review thay đổi hoặc khi code bắt đầu rối.
allowed-tools: Read, Grep, Glob
---

Review code theo tiêu chí clean code, nêu file:dòng + cách sửa:
- Đặt tên rõ ý định; tránh viết tắt khó hiểu, tên gây nhầm.
- Hàm NHỎ, làm MỘT việc; ít tham số; tránh tác dụng phụ ẩn.
- Không lặp (DRY); gom logic trùng thành hàm/đơn vị tái dùng.
- Xử lý lỗi rõ ràng; không “nuốt” lỗi; thông điệp hữu ích.
- Bình luận nói “VÌ SAO”, không mô tả “CÁI GÌ” code đã tự nói.
Đề xuất refactor GIỮ NGUYÊN hành vi; ưu tiên thay đổi nhỏ, an toàn.

Lý thuyết sâu ở khoá riêng

Bài này chỉ mã hoá clean code cho Claude. Muốn hiểu sâu nguyên tắc & thiết kế, xem khoá Clean CodeSOLID trên nền tảng - rồi đưa các quy ước của bạn vào skill này.

Review là để tìm vấn đề lớn; còn định dạng & lỗi vặt thì để máy lo. Một hook PostToolUse chạy formatter/linter sau mỗi lần Claude sửa:

.claude/settings.json - tự format & lint sau khi sửa

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }
        ]
      }
    ]
  }
}
  • Hook = ĐẢM BẢO: code luôn được format/lint, không phụ thuộc Claude “nhớ”.
  • CLAUDE.md giữ luật phong cách ngắn (vd thụt lề, quy ước đặt tên file).
  • Phân vai: hook lo máy-kiểm-được; Skill review lo phần cần “đọc hiểu”.

WCAG đo khả năng truy cập quanh 4 nguyên tắc POUR. Nhắm mức AA (chuẩn thực dụng cho hầu hết dự án):

Nguyên tắcĐiểm kiểm cốt lõi
Perceivable
Cảm nhận được
alt cho ảnh; tương phản chữ ≥ 4.5:1 (chữ to ≥ 3:1); không chỉ dùng MÀU để truyền tin.
Operable
Thao tác được
dùng được bằng BÀN PHÍM; focus thấy rõ; vùng bấm đủ lớn; không bẫy focus.
Understandable
Hiểu được
nhãn rõ cho ô nhập; thông báo lỗi dễ hiểu; hành vi nhất quán.
Robust
Bền vững
HTML NGỮ NGHĨA (button/nav/label…); name/role/value đúng cho trình đọc màn hình.

Kiểm contrast ratio thực tế - nguyên tắc Perceivable của WCAG:

Nhập màu chữ và màu nền để kiểm contrast ratio theo WCAG. Mục tiêu: đạt AA (chuẩn thực dụng cho hầu hết dự án).

Contrast ratio

17.40:1

AA chữ thường: ✓ passAA chữ to: ✓ passAAA chữ thường: ✓ passAAA chữ to: ✓ pass

Mèo con đọc được không?

Đây là đoạn chữ thường - kiểm tra khả năng đọc với tỷ lệ 17.40:1.

HTML ngữ nghĩa trước, ARIA sau

Quy tắc vàng: đừng dùng ARIA nếu HTML thuần đã đủ. Một <button> thật (bấm được bằng bàn phím, có vai trò sẵn) luôn hơn <div role="button"> chắp vá. ARIA chỉ bổ sung khi cần.

Đóng gói các điểm kiểm POUR thành một Skill a11y để Claude tự soi UI:

.claude/skills/a11y-review/SKILL.md

---
name: a11y-review
description: Review giao diện theo WCAG (mức AA). Dùng khi đụng component UI, form, ảnh, màu sắc, hoặc trước khi merge thay đổi giao diện.
allowed-tools: Read, Grep, Glob
---

Review khả năng truy cập theo WCAG POUR, nêu file:dòng + tiêu chí + cách sửa:
- Perceivable: ảnh có alt đúng nghĩa; tương phản ≥ 4.5:1; không chỉ dùng màu.
- Operable: thao tác được bằng bàn phím; focus rõ; dùng phần tử tương tác thật.
- Understandable: mỗi ô nhập có <label>; lỗi báo rõ; hành vi nhất quán.
- Robust: ưu tiên HTML ngữ nghĩa; chỉ thêm ARIA khi HTML thuần không đủ.
Cảnh báo điều CẦN KIỂM TAY: nghĩa của alt, thứ tự đọc, trải nghiệm bàn phím/đọc màn hình.
claude - ~/web-app

Review @src/components/Card.tsx về khả năng truy cập.

⤷ gọi skill: a11y-review (WCAG / POUR)

✗ Operable - nút là <div onclick>: không bấm được bằng bàn phím

✗ Perceivable - <img> thiếu alt; tương phản chữ 2.8:1 < 4.5:1 (AA)

Sửa: đổi <div> thành <button>; thêm alt mô tả; tăng tương phản chữ. Áp dụng chứ?

  • Skill bắt phần máy thấy được; bạn vẫn thử tay bằng bàn phím + trình đọc màn hình.
  • Ghép với hook & subagent: review tự chạy khi đụng UI hoặc trước khi merge.
  • Có lệnh review dựng sẵn (vd /code-review) bổ trợ - nhưng skill theo dự án vẫn quý.

Tổng kết bài

Code của bạn giờ không chỉ đúng & an toàn, mà còn sạchai cũng dùng được - tất cả do Claude tự áp dụng. Bài cuối của mini-track: kiến trúc & mẫu thiết kế senior - giữ hệ thống dễ đổi và chịu lỗi tốt.

Câu hỏi thường gặp

Không. Code được ĐỌC nhiều hơn viết; code rối làm mọi thay đổi sau chậm và dễ sinh bug. Với AI, điều này còn quan trọng hơn: code sạch giúp cả bạn lẫn Claude hiểu nhanh và sửa đúng ở các phiên sau. Clean code là khoản đầu tư cho tốc độ tương lai. (Lý thuyết sâu ở khoá Clean Code & SOLID.)

CLAUDE.md hợp cho LUẬT ngắn luôn đúng (vd “thụt lề 2 dấu cách”). Còn một QUY TRÌNH review nhiều bước (đặt tên, hàm nhỏ, trùng lặp, xử lý lỗi, độ phức tạp…) thì gói thành Skill gọn hơn và chỉ tốn ngữ cảnh khi dùng. Hai thứ bổ trợ nhau.

Là làm sản phẩm dùng được cho MỌI người, kể cả người khiếm thị (dùng trình đọc màn hình), người chỉ dùng bàn phím, người khó phân biệt màu. Quan trọng vì: đó là người dùng thật (số lượng lớn), nhiều nơi còn là YÊU CẦU PHÁP LÝ, và nó cũng làm sản phẩm tốt hơn cho tất cả. WCAG là bộ tiêu chuẩn để đo.

WCAG xoay quanh 4 nguyên tắc POUR: Perceivable (cảm nhận được), Operable (thao tác được), Understandable (hiểu được), Robust (bền vững với công nghệ hỗ trợ). Tiêu chí chia 3 mức: A (tối thiểu), AA (mục tiêu phổ biến của hầu hết dự án), AAA (cao nhất). Nhắm AA là chuẩn thực dụng.

Không hết. Công cụ/skill bắt được nhiều lỗi máy thấy được (thiếu alt, thiếu nhãn, tương phản thấp, không ngữ nghĩa). Nhưng một số thứ cần con người: thứ tự đọc có hợp lý không, alt có MÔ TẢ ĐÚNG ý nghĩa ảnh không, thao tác bàn phím có mượt không. Skill giúp bắt phần lớn; bạn vẫn kiểm tay phần còn lại (vd thử bằng bàn phím + trình đọc màn hình).

Không. Quy tắc số một của ARIA là “đừng dùng ARIA nếu HTML ngữ nghĩa đã đủ”. Một <button> thật tốt hơn một <div role="button"> chắp vá. ARIA chỉ để bổ sung khi HTML thuần không diễn đạt được - dùng sai ARIA còn hại hơn không dùng.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

Vì sao clean code không phải chuyện “cho đẹp”?

  1. 1

    Skill review clean code

    Tạo .claude/skills/clean-code-review/SKILL.md với checklist (đặt tên, hàm nhỏ một việc, trùng lặp, xử lý lỗi). Dùng /clean-code-review trên một file rối.

    Hoàn thành khi: Skill nêu được điểm cần dọn cụ thể (file:dòng) theo checklist; gợi ý refactor giữ nguyên hành vi.

  2. 2

    Hook tự format

    Thêm hook PostToolUse (Write|Edit) chạy formatter + linter của dự án. Sửa thử một file.

    Hoàn thành khi: Sau mỗi lần Claude sửa, code tự được format/lint - không phải nhắc “format lại”.

  3. 3

    Skill review WCAG

    Tạo .claude/skills/a11y-review/SKILL.md theo POUR (alt, nhãn form, tương phản, bàn phím, focus, ngữ nghĩa). Chạy trên một component UI.

    Hoàn thành khi: Skill chỉ ra ít nhất một vi phạm WCAG cụ thể kèm tiêu chí và cách sửa.

  4. 4

    Bắt lỗi a11y thật

    Đưa Claude một nút chỉ là <div onclick> và một <img> không alt. Nhờ skill a11y review.

    Hoàn thành khi: Claude chỉ ra: nên dùng <button> (thao tác bàn phím được) và thêm alt mô tả; nêu đúng nguyên tắc POUR.

  5. 5

    Kiểm tay phần máy không thấy

    Bằng lời: nêu 2 điều về accessibility mà skill khó tự kiểm, bạn phải tự thử.

    Hoàn thành khi: Ví dụ: alt có mô tả ĐÚNG ý nghĩa ảnh không; duyệt toàn trang chỉ bằng bàn phím có mượt & thấy focus không.