Hãy dùng nút bấm
(gomakethings.com)- Trong giao diện web, dùng
thay vìlà lựa chọn đúng đắn hơn về cả khả năng truy cập lẫn chức năng - `` không được trình đọc màn hình nhận diện là phần tử tương tác, đồng thời cũng không phản hồi với tiêu điểm bàn phím hay thao tác nhấn
Enter,Spacebar - Dù thêm thuộc tính
[role="button"]hoặc[tabindex="0"], vẫn còn các vấn đề về thứ tự tiêu điểm và xử lý sự kiện bàn phím - Để khắc phục các vấn đề này, việc thêm nhiều event listener và câu lệnh điều kiện gây ra độ phức tạp không cần thiết
- `` cung cấp sẵn khả năng truy cập, tiêu điểm và xử lý nhập từ bàn phím, nên đây là giải pháp đơn giản và tiêu chuẩn
Cách tiếp cận sai: tạo nút bằng ``
- Trong cộng đồng người dùng React hay HTMX, có khá nhiều trường hợp triển khai tương tác như mở modal bằng dạng ``
- Mã ví dụ:
Open Modal
- Mã ví dụ:
- Vấn đề của cách này
- Trình đọc màn hình không nhận diện phần tử đó là phần tử tương tác
- Không thể di chuyển tiêu điểm bằng bàn phím tới đó
- Chỉ sự kiện
clickhoạt động, còn nhấnEnterhaySpacebarthì không phản hồi
Giới hạn của các nỗ lực “sửa” khả năng truy cập
- Thêm thuộc tính
[role="button"]có thể giải quyết vấn đề nhận diện của trình đọc màn hình, nhưng vấn đề về khả năng nhận tiêu điểm và xử lý nhập từ bàn phím vẫn còn nguyên - Có thể thêm
[tabindex="0"]để cho phép nhận tiêu điểm, nhưng có nguy cơ làm rối thứ tự tiêu điểm hoặc gây ra các lần chuyển không mong muốn - Muốn xử lý nhập từ bàn phím thì phải đăng ký sự kiện
keydownở phạm vi toàn cục (document), phát hiện phímEnterhoặc' '(space), rồi tìm phần tử đang được focus để thực thidocument.addEventListener('keydown', (event) => { if (event.key !== 'Enter' && event.key !== ' ') return; const notRealBtn = document.activeElement.closest('[onclick]'); if (!notRealBtn) return; // 실행 코드 }); - Kết quả là, bạn đang tái hiện một cách phức tạp những gì `` vốn đã cung cấp sẵn theo mặc định
Các tính năng mặc định mà `` cung cấp
- Phần tử `` tự động hỗ trợ những điều sau
- Vai trò ngầm định (
[role="button"]) - Khả năng nhận tiêu điểm tự động
- Khi đang có tiêu điểm, nhấn
EntervàSpacebarsẽ phát sinh sự kiệnclick
- Vai trò ngầm định (
- Nếu muốn triển khai cùng hành vi đó bằng
, bạn sẽ cần **nhiều thuộc tính và script**, còngiải quyết được chỉ với một dòngOpen Modal
Kết luận: đơn giản là tốt nhất
- `` là cách đơn giản nhất để vừa đáp ứng tiêu chuẩn khả năng truy cập vừa giảm lượng mã nguồn
- Thay vì thêm xử lý sự kiện hay thuộc tính không cần thiết, dùng phần tử HTML tiêu chuẩn sẽ có lợi hơn về khả năng bảo trì và hiệu quả
- Với thông điệp “càng lười thì càng nên dùng đúng phần tử”, bài viết nhấn mạnh tầm quan trọng của thói quen phát triển biết tránh độ phức tạp không cần thiết và tận dụng tính năng mặc định
7 bình luận
Đây là một bài viết rất hay. Có thể tóm tắt ý chính của phần nội dung là: "hãy sử dụng các thẻ HTML một cách có ý nghĩa." Nếu cung cấp sự kiện click bằng thẻ
div(hoặc các thẻ khác), thì theo tôi điều đó hoàn toàn không khác gì thời kỳ trước đây khi người ta dùng thẻtableđể dựng layout.Tất nhiên nếu nhét các thuộc tính
aria-*vào thì có thể sẽ rõ ràng hơn, nhưng thay vì phải khổ sở như thế thì thà cứ dùng đúng thẻ còn hơn lolHoài niệm thật nhỉ haha
Hãy dùng button
background, border, outline, appearance, -webkit-appearance, cursor
Có quá nhiều stylesheet mặc định phải ghi đè T_T
Vì vậy mới có CSS Reset.
Các trang web cơ quan công quyền ở nước mình dường như dùng `` rất nhiều...
Ý kiến Hacker News
Một trong những điều khiến tôi khó chịu là các website triển khai điều hướng bằng trình xử lý
onclickChỉ cần dùng thẻ `` thì mở tab mới, tích hợp với công cụ hỗ trợ tiếp cận, menu chuột phải và mọi thứ khác đều tự động hoạt động tốt Nếu là điều hướng thì nên dùng liên kết thay vì một nồi lẩu JavaScriptonClickNgay cả các phần tử về bản chất là liên kết cũng đều bị xử lý bằng click handler, thật khó hiểuHầu hết các nút nên khai báo rõ
type="button"Giá trị mặc định làsubmit, nên nếu ở trong form thì nó sẽ tự động gửi Có lẽ một số lập trình viên không biết điều này nên mới dùng ``, cònthì khácthì có thể tránh được vấn đề `type="submit"`vốn trống ngay từ đầu nên bạn chỉ thêm những chức năng cần thiết, và sau này cũng dễ chỉnh sửa Trong khi đó, để hiểu hành vi mặc định của `` thì phải đọc tài liệu Rốt cuộc đây là vấn đề lựa chọn giữa kiểm soát tường minh vs tính năng tích hợp sẵnSẽ hay hơn nếu bài viết mở rộng theo hướng “hãy dùng đúng phần tử HTML được tạo ra cho mục đích đó” Nhiều lập trình viên SPA không hiểu rõ ngữ nghĩa của các phần tử HTML nên cứ phải phát minh lại bánh xe
Bây giờ đã có cả một thế hệ phải bấm lung tung khắp màn hình để tìm vùng có thể click Mười năm trước có ai đó đã làm cho việc kéo liên kết quan trọng hơn chọn văn bản, nên giờ gần như không thể chọn chữ được nữa Có khi phải fork trình duyệt mới sửa được chuyện này
Tôi từng mất khá lâu loay hoay vì lỗi kích thước flexbox do stylesheet mặc định của Chrome có
button {align-items: flex-start}Dù vậy, tôi vẫn cố dùng đúng phần tử HTML khi có thể, nhưng trong các side project nhỏ thì đôi lúc `` lại tiện hơnappearance: nonehữu ích để reset style nút bấm Tôi tạo class.unbuttonifyđể nó hoạt động như nút nhưng trông theo kiểu khácNên dùng phần tử đúng với mục đích ban đầu của nó bất cứ khi nào có thể
Tôi có hai điều không thích về nút bấm Một là kiểu gì cũng phải style lại cho nó, hai là cảnh báo không thể lồng nút vào nhau Trên thực tế, đây là tình huống gặp khá thường xuyên
LLM thường sinh ra những pattern sai như thế này Chúng hay phớt lờ tính năng mặc định của trình duyệt và triển khai theo cách phức tạp hơn mức cần thiết Tôi thường bảo Claude đơn giản hóa kiểu code như vậy Ngay cả trong TypeScript, chúng cũng có xu hướng làm cách xử lý lỗi trở nên kỳ quặc
Tôi cố gắng mặc định dùng nút bấm bất cứ khi nào có thể Tuy nhiên, nếu về bản chất nó phải hoạt động như liên kết thì tôi dùng thẻ ``
Tôi từng thắc mắc vì sao lại có ý kiến dùng ``