- Hướng dẫn đề xuất các cách nhập đơn giản và có khả năng truy cập cao thay cho bộ chọn ngày JavaScript phức tạp
- Tận dụng phần tử nhập liệu mặc định của trình duyệt (
date, time, datetime-local) để tự động có được khả năng truy cập, hiệu năng và hỗ trợ quốc tế hóa
- Có thể đơn giản hóa UI phức tạp bằng các trường nhập tách biệt, nhập có mặt nạ hoặc nhóm nút radio
- Ngay cả trong các framework như React, bạn vẫn có thể dùng trực tiếp các phần tử nhập HTML mặc định; khả năng tùy biến kiểu dáng có hạn nhưng giữ được UI hệ thống quen thuộc với người dùng
- Mọi bộ chọn ngày đều có vấn đề về khả năng truy cập, vì vậy cấu trúc nhập liệu đơn giản và kiểm thử với người dùng thực là chìa khóa để thiết kế biểu mẫu thành công
Có thực sự cần bộ chọn ngày JavaScript không
- Trong đa số trường hợp, bộ chọn ngày JavaScript riêng là không cần thiết
- UI phức tạp dễ gây lỗi và khiến người dùng bỏ dở biểu mẫu
- Có những cách nhập ngày dễ hơn cả widget lịch
- Mục đích của hướng dẫn này là đưa ra các phương án thay thế cho giao diện thân thiện với người dùng
Nhập ngày và giờ mặc định của trình duyệt
- Mọi trình duyệt hiện đại đều hỗ trợ các kiểu nhập mặc định
date, time, datetime-local
date dùng để chọn ngày, time để nhập giờ và phút, datetime-local kết hợp cả hai
- Trường nhập mặc định có thể được triển khai chỉ với một dòng mã, và trình duyệt sẽ xử lý khả năng truy cập, hiệu năng và quốc tế hóa
- Hỗ trợ nhập bằng bàn phím, cung cấp UI lịch mặc định
- Không hoàn hảo, nhưng ổn định hơn phần lớn thư viện JavaScript
- Tuy vậy, vẫn còn tồn tại một số vấn đề về khả năng truy cập
Trường nhập tách biệt và phần tử chọn
- So với một bộ chọn ngày duy nhất, tách riêng năm, tháng, ngày thành các trường nhập sẽ cải thiện khả năng sử dụng
- Đưa ra ví dụ về component nhập ngày của GOV.UK
- Khi tập giá trị hợp lệ bị giới hạn, nên dùng phần tử
select
- Giúp tránh lỗi nhập liệu, giảm tương tác
- Cần lưu ý việc trình đọc màn hình có thể đọc sai khi tháng được biểu thị bằng số
- Với các khoảng thời gian cố định như đặt chỗ du lịch (ví dụ: từng 15 phút), cách biểu đạt ngày tương đối như hôm nay, ngày mai sẽ hữu ích
Nhập có mặt nạ và kiểm tra hợp lệ
- Trường nhập có mặt nạ là một phương án thay thế giúp định hướng định dạng ngày mà không cần lịch
- Có thể dùng JavaScript để kiểm tra hợp lệ và định dạng ở phía client
- Ví dụ: thông báo lỗi “Hãy nhập ngày hợp lệ của tháng 2 (1~28)”
- Dùng API
Intl để tự động định dạng ngày
- Tuy nhiên, nếu cập nhật giá trị nhập bằng JavaScript thì chức năng undo/redo có thể bị hỏng
- Có thể dùng CSS để kết hợp nhiều trường nhập, giúp chúng trông như một trường duy nhất về mặt thị giác
Chọn phạm vi và các tùy chọn giới hạn
- Bộ chọn ngày theo phạm vi dùng hai lịch rất khó thao tác và bất tiện khi dùng mà không có con trỏ
- Thay vào đó có thể đơn giản hóa bằng hai trường nhập liệu
- Nếu chỉ cần các ngày có thể chọn sẵn, có thể thay bằng nhóm nhập
radio
- Thay UI phức tạp bằng các bước tác vụ đơn giản
- Có thể mở rộng biểu mẫu nhiều bước thành tương tác một trang bằng JavaScript
Nhập tự do và tính năng gợi ý
- Khi không cần ngày hoặc giờ chính xác, trường nhập văn bản cơ bản sẽ hữu ích
- Dùng phần tử
datalist để cung cấp gợi ý nhập liệu
- Cũng hoạt động cùng với các kiểu nhập
date, time
Câu hỏi thường gặp
Khi dùng framework JavaScript
- Tất cả framework lớn đều có thể dùng phần tử HTML mặc định
- Không cần tạo thành component tùy chỉnh
- Có thể ràng buộc trạng thái hai chiều bằng thuộc tính
value
Tùy biến kiểu dáng cho bộ chọn ngày mặc định
- Chỉ có thể style một phần của phần tử
input, phần còn lại thì không
- Đây cũng là một lợi thế để giữ UI hệ thống quen thuộc cho người dùng
- Thiết kế sẽ khác nhau tùy hệ điều hành, phương thức nhập và trình duyệt
- Không cần thiết phải ép thống nhất thiết kế thêm
Cách phản hồi với các bên liên quan yêu cầu bộ chọn ngày JavaScript
- Mục tiêu là gửi biểu mẫu thành công, còn UI phức tạp sẽ làm tăng lỗi
- Mọi bộ chọn ngày đều tồn tại vấn đề về khả năng truy cập
- Tổ hợp các trường nhập mặc định thân thiện với người dùng hơn
- UI JavaScript chưa được kiểm chứng có thể vi phạm các quy định như Đạo luật Khả năng tiếp cận Châu Âu (EAA)
- Sự đơn giản là chìa khóa của thành công
Kiểm thử và bảo đảm khả năng truy cập
- Cần hiểu rõ các hướng dẫn về khả năng truy cập như WCAG
- Tận dụng tiêu chuẩn web để tránh lỗi từ UI tùy chỉnh
- Có thể phát hiện lỗi bằng các tính năng hỗ trợ truy cập trong công cụ dành cho nhà phát triển của trình duyệt
- Không có công cụ nào hoàn hảo, và kiểm thử với người dùng thực là cách xác thực duy nhất
- Rất không khuyến khích dùng accessibility overlay, vì có thể làm vấn đề tệ hơn
Tài liệu tham khảo về khả năng truy cập
- Collecting dates in an accessible way — Graham Armfield
- What makes an accessible date picker? — Russ Weakley
- Maybe You Don’t Need a Date Picker — Adrian Roselli
- Date Picker Dialog Example — ARIA Authoring Practices Guide
- Designing The Perfect Date And Time Picker — Vitaly Friedman
Câu trả lời cho yêu cầu đề xuất bộ chọn ngày JavaScript
- Không có giải pháp phổ quát, mọi bộ chọn ngày đều có giới hạn
- Hướng dẫn này nhằm giúp bạn tự đánh giá yêu cầu của mình
- Khuyến nghị đạt mục tiêu bằng cách đơn giản nhất có thể
- Có thể bạn không thực sự cần bộ chọn ngày
Kết luận
- Kiểm thử với người dùng thực và thu thập phản hồi là điều bắt buộc
- Hướng dẫn này vẫn đang tiếp tục được hoàn thiện và luôn hoan nghênh phản hồi
1 bình luận
Ý kiến trên Hacker News
Thực sự đã có những câu như “không thể đặt năm sinh”, “để tới ngày sinh của tôi phải bấm mũi tên về tháng trước 720 lần”
Trên cả iOS lẫn Android khi đó, năm chỉ hiện như một tiêu đề đơn thuần nên không được nhận ra là phần tử có thể nhấp
Tôi cảm thấy Flat Design quá thiên về thẩm mỹ đang phá hỏng UX. Tôi nghĩ vấn đề nằm ở thực tế là UI của OS được quyết định chủ yếu bởi nhà thiết kế chứ không phải các chuyên gia UX như Don Norman
Cuối cùng, khi đổi sang dạng hộp văn bản - danh sách thả xuống - hộp văn bản (ngày-tháng-năm), các lời phàn nàn đã biến mất
Họ nói rằng ba ô văn bản riêng (ngày, tháng, năm) mang lại trải nghiệm tốt nhất.
Cũng có hướng dẫn mẫu để triển khai
Nhưng khi đặt chuyến bay gần nửa đêm thì lại không rõ “hôm nay” là theo múi giờ của tôi, của máy chủ hay GMT
Có quá nhiều ngoại lệ như múi giờ, giờ mùa hè, cuối tháng (31 tháng 1 → tháng sau?), ngay sau nửa đêm.
Trước khi thêm kiểu tính năng này thật sự phải cực kỳ thận trọng
Khi làm việc qua 12 giờ đêm, cách diễn đạt “ngày mai” không còn khớp với cảm nhận thực tế.
Trên thực tế ý tôi là “sau sáng nay”, nhưng hệ thống lại hiểu là ngày hôm sau
input type="text"và cho gợi ý định dạngNhư vậy sẽ không phải vật lộn với trình duyệt, khả năng truy cập hay vấn đề locale
Component tự làm đúng là cánh cổng dẫn xuống địa ngục. Chỉ vì muốn trông đẹp mà rơi vào 10 cái hang thỏ
Vì khi đó phải khám phá ngày theo trực quan
Vấn đề ngày tháng thực sự rất phức tạp nên cần cách tiếp cận theo từng trường hợp sử dụng
Nếu làm hệ thống bệnh viện ở Nepal thì phải hỗ trợ cả lịch Nepal lẫn lịch Gregory thông thường. Lịch Nepal rất phức tạp
Ethiopia dùng lịch 13 tháng, trong đó tháng cuối chỉ có 5~6 ngày
Nếu ai biết tài liệu tham khảo tốt về date picker quốc tế hóa thì tôi rất muốn xem
Ví dụ, đặt bàn ăn tối thì lịch hữu ích để xem cuối tuần nào còn chỗ, nhưng nhập ngày sinh thì gõ số nhanh sẽ hiệu quả hơn
quy trình kiểu chọn tên tháng → dropdown → chọn năm sẽ phá vỡ nhịp điệu
Cứ để người dùng nhập số đơn thuần sẽ tự nhiên hơn nhiều. Trên di động lại còn bất tiện hơn vì bàn phím cứ mở rồi đóng liên tục
Việc ép dùng custom picker thay vì UI mặc định thật kỳ lạ.
Đặc biệt, việc bắt chước bộ chọn thời gian dạng bánh xe xoay kiểu iOS trên web, nhất là trên Android, là tệ nhất
Còn cần cả bộ chọn theo tháng, theo tuần, và bộ chọn khoảng thời gian tùy chỉnh nữa. Các phần tử form native quá hạn chế
<input type="week">hay<input type="month">còn thiếu gì không