Tô đỏ viền là tín hiệu chỉ dành cho mắt. Cần ba mảnh ghép:
1. Đánh dấu ô lỗi: aria-invalid="true" để screen reader đọc "không hợp lệ" khi focus vào ô. Bỏ về false/gỡ hẳn khi người dùng sửa xong.
2. Nối thông báo lỗi vào ô: aria-describedby trỏ tới id của phần tử chứa nội dung lỗi — screen reader đọc nhãn, rồi đọc mô tả lỗi ngay sau đó.
<label for="email">Email</label>
<input id="email" type="email" aria-invalid="true" aria-describedby="email-err">
<p id="email-err">Email phải có dạng ten@mien.com</p>3. Đưa người dùng tới lỗi: sau khi submit hỏng, chuyển focus vào ô lỗi đầu tiên (hoặc vào phần tóm tắt lỗi đầu trang có tabindex="-1"). Nếu chỉ render danh sách lỗi mà không chuyển focus, người dùng bàn phím vẫn đứng ở nút submit và không biết có gì đã đổi.
Chi tiết thực chiến:
- Nội dung lỗi phải nói cách sửa, không chỉ "Không hợp lệ" (WCAG 3.3.3).
- Dùng aria-describedby cho lỗi, <label> cho nhãn — đừng nhồi lỗi vào aria-label vì nó thay luôn nhãn.
- Một ô có thể trỏ nhiều id (aria-describedby="email-hint email-err").
- Nếu lỗi xuất hiện ngay lúc gõ, bọc thêm live region để thông báo — nhưng để polite để không ngắt lời người dùng ở mỗi ký tự.