Bảng

Bảng HTML được dùng để trình bày dữ liệu dạng bảng có hàng và cột. Quyết định sử dụng <table> phải dựa trên nội dung bạn đang trình bày và nhu cầu của người dùng liên quan đến nội dung đó. Nếu dữ liệu đang được trình bày, so sánh, sắp xếp, tính toán hoặc tham chiếu chéo, thì <table> có thể là lựa chọn phù hợp. Nếu bạn chỉ muốn bố trí nội dung không theo bảng một cách gọn gàng, chẳng hạn như một nhóm lớn gồm nhiều hình thu nhỏ, thì các bảng sẽ không phù hợp: thay vào đó, hãy tạo danh sách hình ảnh và tạo kiểu cho lưới bằng CSS.

Trong phần này, chúng ta sẽ thảo luận về tất cả thành phần tạo nên bảng, cùng với một số tính năng hỗ trợ tiếp cận và khả năng hữu dụng mà bạn nên cân nhắc khi trình bày dữ liệu dạng bảng. Mặc dù về cơ bản, Tìm hiểu HTML không phải là về CSS và có toàn bộ khoá học dành riêng cho việc tìm hiểu CSS, nhưng chúng tôi sẽ đề cập đến một số thuộc tính CSS dành riêng cho bảng.

Các phần tử trong bảng, theo thứ tự

Thẻ <table> bao bọc nội dung bảng, bao gồm cả mọi phần tử của bảng. Vai trò ARIA ngầm ẩn của <table>table; các công nghệ hỗ trợ biết rằng phần tử này là một cấu trúc bảng chứa dữ liệu được sắp xếp trong hàng và cột. Nếu bảng duy trì trạng thái lựa chọn, có thành phần điều hướng hai chiều hoặc cho phép người dùng sắp xếp lại thứ tự ô, hãy đặt role="grid". Nếu có thể mở rộng và thu gọn các hàng của grid, hãy dùng role="treegrid".

Bên trong <table>, bạn sẽ tìm thấy tiêu đề bảng (<thead>), nội dung bảng (<tbody>) và chân trang bảng (<tfoot>) (không bắt buộc). Mỗi mục trong số này được tạo thành từ các hàng trong bảng (<tr>). Hàng chứa tiêu đề bảng (<th>) và ô dữ liệu bảng (<td>) lần lượt chứa tất cả dữ liệu. Trong DOM, trước bất kỳ tính năng nào, bạn có thể thấy hai tính năng bổ sung: chú thích bảng (<caption>) và nhóm cột (<colgroup>). Tuỳ thuộc vào việc <colgroup> có thuộc tính span hay không, nó có thể chứa các phần tử cột bảng lồng nhau (<col>).

Các phần tử con của bảng được sắp xếp theo thứ tự:

  1. Phần tử <caption>
  2. Phần tử <colgroup>
  3. Phần tử <thead>
  4. Phần tử <tbody>
  5. Phần tử <tfoot>

Chúng ta sẽ đề cập đến các phần tử con của các phần tử <table>. Tất cả các phần tử con này đều không bắt buộc nhưng nên dùng, sau đó hãy xem xét các hàng, ô tiêu đề trong bảng và các ô dữ liệu trong bảng. <colgroup> sẽ được đề cập sau cùng.

Chú thích bảng

Là một phần tử ngữ nghĩa gốc, <caption> là phương thức ưu tiên để đặt tên cho bảng. <caption> cung cấp tiêu đề bảng mang tính mô tả và được liên kết theo phương thức lập trình. Tệp này sẽ hiển thị và có sẵn cho tất cả người dùng theo mặc định.

Phần tử <caption> phải là phần tử đầu tiên được lồng trong phần tử <table>. Khi thêm thuộc tính này, tất cả người dùng sẽ biết mục đích của bảng ngay lập tức mà không cần phải đọc văn bản xung quanh. Ngoài ra, bạn có thể dùng aria-label hoặc aria-labelledby trên <table> để cung cấp tên thành phần hỗ trợ tiếp cận làm chú thích. Phần tử <caption> không có thuộc tính riêng của phần tử nào.

Chú thích đó sẽ xuất hiện ngoài bảng. Bạn có thể đặt vị trí của phụ đề bằng thuộc tính CSS caption-side. Đây là một phương pháp hay so với việc sử dụng thuộc tính align đã ngừng hoạt động. Thao tác này có thể đặt phụ đề lên trên cùng và dưới cùng. Vị trí bên trái và bên phải, với inline-startinline-end, chưa được hỗ trợ đầy đủ. Trên cùng là bản trình bày mặc định của trình duyệt.

Tốt nhất là bảng dữ liệu nên có tiêu đề và chú thích rõ ràng, đồng thời đủ đơn giản để gần như tự giải thích. Hãy lưu ý rằng không phải tất cả người dùng đều có khả năng nhận thức như nhau. Khi bảng đang "đưa ra một quan điểm" hoặc cần diễn giải, hãy tóm tắt nội dung tóm tắt ngắn gọn về ý hoặc chức năng chính của bảng. Vị trí đặt phần tóm tắt tuỳ thuộc vào độ dài và độ phức tạp của bản tóm tắt. Nếu ngắn gọn, hãy sử dụng dòng tiêu đề đó làm nội dung của phụ đề. Nếu dài hơn, hãy tóm tắt nội dung trong phần chú thích và cung cấp thông tin tóm tắt ở đoạn trước bảng, liên kết hai nội dung đó với thuộc tính aria-describedby. Một tuỳ chọn khác là đặt bảng vào <figure> và đặt phần tóm tắt vào <figcaption>.

Phân mục dữ liệu

Nội dung của bảng bao gồm tối đa 3 phần: không hoặc nhiều tiêu đề bảng (<thead>), phần nội dung bảng (<tbody>) và chân trang bảng (<tfoot>). Tất cả đều không bắt buộc, trong đó mỗi phần đều không được hỗ trợ.

Những thành phần này không giúp hoặc cản trở khả năng tiếp cận của bảng, nhưng hữu ích về mặt tính hữu dụng. Chúng cung cấp những nét hấp dẫn trong tạo kiểu. Ví dụ: nội dung tiêu đề có thể làm cố định, trong khi nội dung <tbody> có thể cuộn được. Các hàng không lồng vào một trong 3 phần tử chứa này sẽ được ngầm gói trong một <tbody>. Cả ba đều có cùng vai trò ngầm ẩn rowgroup. Không có phần tử nào trong số 3 phần tử này có bất kỳ thuộc tính riêng nào của từng phần tử.

Những gì chúng tôi có cho đến nay:

<table>
  <caption>MLW Students</caption>
  <thead></thead>
  <tbody></tbody>
  <tfoot></tfoot>
</table>

Ban đầu, phần tử <tfoot> được chỉ định để xuất hiện ngay sau <thead> và trước <tbody> vì lý do hỗ trợ tiếp cận. Đó là lý do bạn có thể gặp phải thứ tự nguồn không trực quan này trong các cơ sở mã cũ.

Nội dung bảng

Bảng có thể được chia thành tiêu đề, nội dung và chân trang bảng, nhưng sẽ không có dữ liệu nào trong số này thực sự có tác dụng nếu bảng không chứa hàng, ô và nội dung của bảng. Mỗi hàng của bảng, <tr> chứa một hoặc nhiều ô. Nếu một ô là ô tiêu đề, hãy sử dụng <th>. Nếu không, hãy sử dụng <td>.

Biểu định kiểu tác nhân người dùng thường hiển thị nội dung trong ô tiêu đề của bảng <th> ở dạng chính giữa và in đậm. Các kiểu mặc định này và tất cả các kiểu đều được kiểm soát tốt nhất bằng CSS thay vì các thuộc tính không dùng nữa từng có sẵn trên từng ô, hàng và thậm chí là <table>.

Đã có các thuộc tính để thêm khoảng đệm giữa các ô và trong các ô, đối với đường viền và để căn chỉnh văn bản. Bạn phải đặt khoảng cách giữa các ô liền kề và khoảng cách ô xác định khoảng cách giữa nội dung của một ô và đường viền của ô, cũng như giữa đường viền của các ô liền kề bằng các thuộc tính border-collapseborder-spacing của CSS. Border-spacing sẽ không có hiệu lực nếu bạn đặt border-collapse: collapse. Nếu đặt border-collapse: separate;, bạn có thể ẩn hoàn toàn các ô trống bằng empty-cells: hide;. Để tìm hiểu thêm về cách tạo kiểu cho bảng, dưới đây là một trang trình bày tương tác về các kiểu CSS liên quan đến bảng.

Trong các ví dụ, chúng tôi đã thêm đường viền trên bảng và từng ô riêng lẻ có CSS để làm cho một số tính năng rõ ràng hơn:

Trong ví dụ này, chúng ta có chú thích, tiêu đề bảng và nội dung bảng. Tiêu đề có một hàng chứa ba ô <th> tiêu đề, do đó tạo ra ba cột. Phần nội dung chứa ba hàng dữ liệu: ô đầu tiên là ô tiêu đề cho hàng, vì vậy, chúng ta sử dụng <th> thay vì <td>.

Ô <th> có ý nghĩa ngữ nghĩa, với các vai trò ARIA ngầm ẩn của columnheader hoặc rowheader. Hàm này xác định ô làm tiêu đề cho cột hoặc hàng gồm các ô trong bảng, tuỳ thuộc vào giá trị của thuộc tính scope liệt kê. Trình duyệt sẽ mặc định là col hoặc row nếu bạn không đặt scope một cách rõ ràng. Vì chúng ta đã sử dụng mã đánh dấu ngữ nghĩa nên ô 1956 có hai tiêu đề: Năm và Lou Minious. Mối liên kết này cho chúng tôi biết rằng "1956" là "năm" tốt nghiệp của "Lou Minious". Trong ví dụ này, như chúng ta có thể thấy toàn bộ bảng, mối liên kết rất rõ ràng. Việc sử dụng <th> sẽ cung cấp mối liên kết ngay cả khi người dùng cuộn để không nhìn thấy cột tiêu đề hoặc hàng. Chúng ta có thể thiết lập <th scope="col">Year</th><th scope="row">Lou Minious</th> một cách rõ ràng, nhưng với một bảng đơn giản như thế này, các giá trị mặc định được liệt kê sẽ hoạt động. Các giá trị khác của scope bao gồm rowgroupcolgroup, rất hữu ích với các bảng phức tạp.

Hợp nhất ô

Tương tự như MS Excel, Google Trang tính và Số, bạn có thể kết hợp nhiều ô thành một ô duy nhất. Việc này được thực hiện bằng HTML! Thuộc tính colspan dùng để hợp nhất hai hoặc nhiều ô liền kề trong một hàng duy nhất. Thuộc tính rowspan dùng để hợp nhất các ô trên nhiều hàng, được đặt trên ô ở hàng trên cùng.

Trong ví dụ này, tiêu đề bảng chứa hai hàng. Hàng tiêu đề đầu tiên chứa 3 ô trải dài 4 cột: ô ở giữa có colspan="2". Thao tác này sẽ hợp nhất hai ô liền kề. Các ô đầu tiên và cuối cùng bao gồm rowspan="2". Thao tác này sẽ hợp nhất ô với ô trong hàng liền kề, ngay bên dưới ô đó.

Hàng thứ hai trong tiêu đề bảng chứa hai ô; đây là các ô cho cột thứ hai và thứ ba trong hàng thứ hai. Không có ô nào được khai báo cho cột đầu tiên hoặc cột cuối cùng khi ô ở cột đầu tiên và cuối cùng trong hàng đầu tiên trải dài hai hàng.

Trong trường hợp một ô được xác định bằng nhiều ô tiêu đề chứa các mối liên kết mà chỉ có thuộc tính scope không thể đặt, hãy thêm thuộc tính headers cùng với danh sách tiêu đề liên kết được phân tách bằng dấu cách. Do ví dụ này là một bảng phức tạp hơn, nên chúng ta xác định rõ phạm vi của tiêu đề bằng thuộc tính scope. Để rõ ràng hơn, chúng ta thêm thuộc tính headers vào từng ô.

Có thể bạn không cần các thuộc tính headers trong một trường hợp sử dụng đơn giản như vậy, nhưng các thuộc tính này rất quan trọng trong thanh công cụ vì các bảng của bạn tăng độ phức tạp. Các bảng có cấu trúc phức tạp, chẳng hạn như bảng có các tiêu đề hoặc ô được hợp nhất hoặc có nhiều hơn hai cấp tiêu đề cột hoặc hàng, yêu cầu xác định rõ ràng các ô tiêu đề liên kết. Trong các bảng phức tạp như vậy, hãy liên kết rõ ràng từng ô dữ liệu với từng ô tiêu đề tương ứng với một danh sách giá trị id được phân tách bằng dấu cách của tất cả tiêu đề đã liên kết làm giá trị của thuộc tính headers.

Thuộc tính headers thường thấy trên các phần tử <td>, nhưng cũng hợp lệ trên <th>.

Điều đó có nghĩa là cấu trúc bảng phức tạp có thể khó hiểu đối với tất cả người dùng, không chỉ người dùng trình đọc màn hình. Về mặt nhận thức và hỗ trợ trình đọc màn hình, các bảng đơn giản hơn, có ít hoặc không có ô được mở rộng, ngay cả khi không thêm phạm vi và tiêu đề, sẽ dễ hiểu hơn. Việc quản lý các thành phần này cũng dễ dàng hơn!

Tạo kiểu cho bảng

Có 2 phần tử tương đối ít được biết đến được đề cập ngắn gọn: nhóm cột <colgroup>, phần tử và phần tử con duy nhất của nó là phần tử cột <col> trống. Phần tử <colgroup> dùng để xác định các nhóm cột hoặc phần tử <col> trong một bảng.

Nếu được sử dụng, nhóm cột phải được lồng trong <table>, ngay sau <caption> và trước bất kỳ dữ liệu bảng nào. Nếu các biến này nằm trong nhiều cột, hãy sử dụng thuộc tính span.

Thứ tự phác thảo nội dung của một bảng thường như sau, trong đó <table><caption> là hai phần tử cần được đưa vào:

<table>
  <caption>Table Caption</caption>
  <colgroup>
    <col/>
  </colgroup>
  <thead>...

Cả <colgroup><col> đều không có ý nghĩa ngữ nghĩa khi giúp bảng dễ truy cập hơn, nhưng chúng cho phép định kiểu cột có giới hạn, bao gồm cả việc đặt chiều rộng cho cột bằng CSS.

Kiểu <col> sẽ tạo kiểu cho một cột miễn là không có kiểu <td> hoặc <th> nào ghi đè kiểu đó. Ví dụ: khi <colspan> dùng để hợp nhất các ô trong một số hàng của bảng nhưng không phải tất cả, bạn không thể chắc chắn rằng một bộ chọn, chẳng hạn như tr > *:nth-child(8), chọn ô con thứ 8 của mỗi hàng, sẽ đánh dấu toàn bộ cột thứ 8 hoặc sẽ đánh dấu cột thứ 8 cho một số hàng, nhưng với một vài ô cột thứ 9 và thứ 10, tuỳ thuộc vào ô hàng hoặc cột nào được hợp nhất.

Rất tiếc, chỉ một số thuộc tính được hỗ trợ, các kiểu không được kế thừa vào các ô và cách duy nhất để sử dụng phần tử <col> trong các ô nhắm mục tiêu là dùng một bộ chọn phức tạp, bao gồm cả bộ chọn quan hệ :has().

Kết xuất theo lớp của các phần tử được sử dụng để thiết kế bảng HTML.

Nếu cả <table><colgroup> đều có màu nền, thì background-color của <colgroup> sẽ ở trên cùng. Thứ tự vẽ là: bảng, nhóm cột, cột, nhóm hàng, hàng, với các ô ở cuối và trên cùng, như minh hoạ trong giản đồ về các lớp trong bảng. Các phần tử <td><th> không phải là con cháu của các phần tử <colgroup> hoặc <col> và không kế thừa kiểu của chúng.

Để đánh dấu bảng, bạn có thể sử dụng bộ chọn cấu trúc CSS. Ví dụ: tbody tr:nth-of-type(odd) {background-color: rgba(0 0 0 / 0.1);} sẽ thêm một màu đen mờ vào mỗi hàng lẻ trong nội dung của bảng, cho phép mọi hiệu ứng nền được đặt trên <colgroup> hiển thị.

Theo mặc định, các bảng không phản hồi. Thay vào đó, theo mặc định, các kích thước này được định kích thước theo nội dung. Bạn cần có thêm các biện pháp để tạo kiểu bố cục bảng hoạt động hiệu quả trên nhiều thiết bị. Nếu bạn đang thay đổi thuộc tính hiển thị CSS cho các phần tử bảng, hãy thêm các thuộc tính role của ARIA. Mặc dù điều đó nghe có vẻ dư thừa, nhưng thuộc tính displayCSS có thể ảnh hưởng đến cây hỗ trợ tiếp cận trong một số trình duyệt.

Đang trình bày dữ liệu

Các phần tử bảng có ý nghĩa ngữ nghĩa được các công nghệ hỗ trợ sử dụng để cho phép điều hướng qua các hàng và cột mà không bị "bị mất". Không được sử dụng phần tử <table> để trình bày. Nếu bạn cần tiêu đề trên danh sách, hãy sử dụng tiêu đềdanh sách. Nếu bạn muốn bố trí nội dung trong nhiều cột, hãy sử dụng bố cục nhiều cột. Nếu bạn muốn bố trí nội dung trong một lưới, hãy sử dụng lưới CSS. Chỉ sử dụng bảng cho dữ liệu. Hãy nghĩ theo cách này: nếu dữ liệu của bạn yêu cầu một bảng tính để được trình bày trong cuộc họp, hãy sử dụng <table>. Nếu muốn sử dụng các tính năng có trong phần mềm trình bày như Keynote hoặc PowerPoint, bạn có thể cần danh sách nội dung mô tả.

Mặc dù cột trong bảng sắp xếp là mục đích của JavaScript, nhưng việc đánh dấu tiêu đề của bạn để cho người dùng biết cột có thể sắp xếp là mục đích sử dụng HTML. Cho người dùng biết các cột trong bảng có thể sắp xếp được, kèm theo biểu tượng hình ảnh tăng dần, giảm dần hoặc chưa được sắp xếp. Cột hiện được sắp xếp phải bao gồm thuộc tính aria-sort có giá trị được liệt kê của hướng sắp xếp. <caption> có thể thông báo lịch sự về các nội dung cập nhật để sắp xếp thứ tự thông qua aria-live và một span được cập nhật động mà người dùng trình đọc màn hình sẽ nhìn thấy. Vì có thể sắp xếp cột này bằng cách nhấp vào nội dung tiêu đề, nên nội dung tiêu đề phải là <button>.

Nếu bạn không trình bày dữ liệu dạng bảng thì đừng sử dụng <table>. Nếu bạn dùng bảng để trình bày, hãy đặt role="none".

Nhiều nhà phát triển sử dụng bảng để bố trí biểu mẫu nhưng không cần thiết. Nhưng bạn cần phải biết về biểu mẫu HTML, vì vậy chúng tôi sẽ đề cập đến nội dung đó trong phần tiếp theo.

Kiểm tra kiến thức

Kiểm tra kiến thức của bạn về bảng.

Phần tử nào được dùng để đánh dấu các ô là tiêu đề?

<header>
Hãy thử lại.
<caption>
Hãy thử lại.
<th>
Chính xác!

Thông tin nào có thể phù hợp với bố cục có bảng?

Một số thuật ngữ khoa học và nội dung mô tả.
Hãy thử lại, tuỳ chọn này phù hợp hơn với <dl>.
Một bảng tính thông tin chi tiết về học viên và điểm số của họ trong 3 học kỳ.
Chính xác!
Nguyên liệu cho một công thức nấu ăn.
Hãy thử lại, tuỳ chọn này phù hợp hơn với <ul>.