- Trong giao diện web, dùng
<button> thay vì <div> là lựa chọn đúng đắn hơn về cả khả năng truy cập lẫn chức năng
<div> 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
<button> 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 <div>
- 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
<div onclick="...">
- 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
click hoạt động, còn nhấn Enter hay Spacebar thì 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
Các tính năng mặc định mà <button> cung cấp
Kết luận: đơn giản là tốt nhất
<button> 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
Các trang web cơ quan công quyền ở nước mình dường như dùng
<a>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ẻ
<a>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ốtNếu là điều hướng thì nên dùng liên kết thay vì một nồi lẩu JavaScript
Có lẽ do ảnh hưởng của framework hoặc do sự thờ ơ
Dù vậy, cách truyền thống gần như luôn tốt hơn về mặt UX
Tôi mong những ai cố thay thế thẻ
<a>sẽ gặp một chút bất tiệnNhững người này tạo ra các pattern sai, rồi các lập trình viên đi sau cứ thế làm theo
Rất hiếm khi tôi thực sự phải trang trí một
<div>để nó trông như nút bấmTôi hay cuộn bằng nút giữa chuột, nhưng nhiều website làm hỏng chức năng này
Nhấp chuột trái thì hiện trang kiểm tra an toàn, còn nhấp chuột giữa thì đi thẳng luôn
onClickNgay 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ểu
Hầ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ửiCó lẽ một số lập trình viên không biết điều này nên mới dùng
<div>Nút với kiểu mặc định hoạt động kỳ quặc và đôi khi còn bỏ qua JS handler
<input type="submit">, còn<button>thì khác<div>thì có thể tránh được vấn đềtype="submit"<div>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ửaTrong khi đó, để hiểu hành vi mặc định của
<button>thì phải đọc tài liệuRố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ẵn
Sẽ 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
Ví dụ date picker mặc định quá xấu nên người ta lại thay bằng bản dựa trên JS
Đó là bối cảnh khiến các nút tùy biến xuất hiện
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
Nếu giữ Alt (hoặc Option) thì có thể chọn văn bản bên trong liên kết
Đó thực sự là hành vi không mong muốn
Dùng ứng dụng TextSniper trên macOS thì có thể chọn vùng và dùng OCR để sao chép chữ
Nhờ đó mà Google Analytics cũng đỡ khó dùng hơn một chút
Những vấn đề như vậy cần được nhắc đến thường xuyên hơn
Trước đây là Select Like A Boss, giờ gọi là Drag-Select Link Text
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
<div>lại tiện hơnappearance: nonehữu ích để reset style nút bấmTô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ẻ
<a><a>Tôi từng thắc mắc vì sao lại có ý kiến dùng
<div><div>thuận tiện hơn cho các kiểu tùy biến hình thức kỳ quặcThế là nó vừa không giống nút bấm, vừa không hoạt động như nút bấm
<div onclick>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.