Bảng

Bảng HTML dùng để hiển thị 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 phải dạng bảng một cách gọn gàng, chẳng hạn như một nhóm lớn hình thu nhỏ, thì bảng không phù hợp: thay vào đó, hãy tạo một 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ả các phần tử 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ù khoá học Học HTML không tập trung vào CSS và có một khoá học dành riêng cho việc tìm hiểu CSS, nhưng chúng ta 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ả tất cả các phần tử 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 theo hàng và cột. Nếu bảng duy trì trạng thái lựa chọn, có thao tác đ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ác hàng của grid có thể mở rộng và thu gọn, hãy sử dụng role="treegrid".

Bên trong <table>, bạn sẽ 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 phần này được tạo thành từ các hàng bảng (<tr>). Các hàng chứa các ô tiêu đề bảng (<th>) và dữ liệu bảng (<td>), từ đó chứa tất cả dữ liệu. Trong DOM, trước khi tìm thấy bất kỳ tính năng nào trong số này, 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, thuộc tính này 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 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 phần tử <table> (không bắt buộc nhưng nên dùng), sau đó xem xét các hàng, ô tiêu đề bảng và ô dữ liệu bảng. <colgroup> sẽ được đề cập ở phần cuối.

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 mô tả, được liên kết theo phương thức lập trình. Theo mặc định, tất cả người dùng đều có thể nhìn thấy và sử dụng tính năng này.

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

Chú thích xuất hiện bên ngoài bảng. Bạn có thể đặt vị trí của chú thích bằng thuộc tính CSS caption-side. Đây là một phương pháp hay hơn so với việc sử dụng thuộc tính align không còn được dùng nữa. Thao tác này có thể đặt chú thích ở trên cùng và dưới cùng. Vị trí bên trái và bên phải bằng 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 phải có tiêu đề và chú thích rõ ràng, đồng thời đủ đơn giản để gần như tự giải thích được. Xin lưu ý rằng không phải người dùng nào cũng có cùng khả năng nhận thức. Khi bảng "đưa ra một điểm" hoặc cần được diễn giải, hãy cung cấp một bản tóm tắt ngắn gọn về điểm chính hoặc chức năng của bảng. Vị trí đặt bản tóm tắt đó phụ 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 nội dung đó làm văn bản bên trong của chú thích. Nếu dài hơn, hãy tóm tắt trong chú thích và cung cấp bản tóm tắt trong đoạn văn trước bảng, liên kết hai phần này với thuộc tính aria-describedby. Bạn cũng có thể đặt bảng trong <figure> và đặt phần tóm tắt trong <figcaption>.

Phân đoạn dữ liệu

Nội dung của bảng bao gồm tối đa 3 phần: từ 0 đến 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, mỗi phần có thể có từ 0 đến nhiều phần được hỗ trợ.

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

Những gì chúng ta 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 ngay sau <thead> và trước <tbody> vì lý do hỗ trợ tiếp cận. Đó là lý do bạn có thể thấy thứ tự nguồn không trực quan này trong các cơ sở mã cũ.

Nội dung bảng

Bạn có thể chia bảng thành tiêu đề, nội dung và chân trang, nhưng không có phần 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. Mỗi hàng trong 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>.

Tệp kiểu của tác nhân người dùng thường hiển thị nội dung trong ô tiêu đề bảng <th> ở giữa và in đậm. Tốt nhất là bạn nên kiểm soát các kiểu mặc định này và tất cả kiểu bằng CSS thay vì các thuộc tính không dùng nữa từng có trên các ô, hàng riêng lẻ 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 ô, cho đường viền và để căn chỉnh văn bản. Cellpadding và cellspacing, xác định khoảng trống giữa nội dung của một ô và đường viền của ô đó, cũng như giữa các đường viền của các ô liền kề, nên được đặt bằng các thuộc tính CSS border-collapseborder-spacing tương ứng. 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, sau đây là một bản trình bày dạng trình chiếu 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ẻ bằng CSS để làm cho một số tính năng trở nên 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. Phần đầu có một hàng chứa ba ô <th> tiêu đề, tạo ra ba cột. Phần nội dung chứa 3 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 là columnheader hoặc rowheader. Thuộc tính này xác định ô là tiêu đề cho cột hoặc hàng của các ô trong bảng, tuỳ thuộc vào giá trị của thuộc tính scope được liệt kê. Trình duyệt sẽ mặc định là col hoặc row nếu bạn không đặt rõ ràng scope. 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 ta biết rằng "1956" là "năm" tốt nghiệp của "Lou Minious". Trong ví dụ này, chúng ta có thể thấy toàn bộ bảng, mối liên kết sẽ xuất hiện rõ ràng. Việc sử dụng <th> sẽ cung cấp mối liên kết ngay cả khi cột hoặc hàng tiêu đề đã cuộn ra khỏi chế độ xem. Chúng ta có thể đặt rõ ràng <th scope="col">Year</th><th scope="row">Lou Minious</th>, 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à Numbers, bạn có thể hợp nhất nhiều ô thành một ô. Bạn có thể thực hiện việc này bằng HTML! Thuộc tính colspan được dùng để hợp nhất hai hoặc nhiều ô liền kề trong một hàng. Thuộc tính rowspan được dùng để hợp nhất các ô trên các 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 ba ô trải dài trên bốn cột: ô ở giữa có colspan="2". Thao tác này sẽ hợp nhất hai ô liền kề. Ô đầ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 vì ô trong cột đầu tiên và cột cuối cùng trong hàng đầu tiên trải dài trên hai hàng.

Trong trường hợp một ô được xác định bởi nhiều ô tiêu đề có các mối liên kết không thể được đặt chỉ bằng thuộc tính scope, hãy thêm thuộc tính headers với danh sách các tiêu đề được liên kết được phân tách bằng dấu cách. Vì ví dụ này là một bảng phức tạp hơn, nên chúng ta xác định rõ ràng 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ác thuộc tính headers có thể không cần thiết trong trường hợp sử dụng đơn giản như vậy, nhưng bạn cần có các thuộc tính này trong bộ công cụ khi bảng của bạn trở nên phức tạp hơn. Các bảng có cấu trúc phức tạp, chẳng hạn như bảng mà 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 đề được 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 bằng danh sách các giá trị id được phân tách bằng dấu cách của tất cả các tiêu đề được liên kết làm giá trị của thuộc tính headers.

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

Tuy nhiên, tất cả người dùng, không chỉ người dùng trình đọc màn hình, đều có thể khó hiểu các cấu trúc bảng phức tạp. Về mặt nhận thức và khả năng 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ũng dễ dàng hơn!

Tạo kiểu cho bảng

Có hai phần tử tương đối khó hiểu được đề cập ngắn gọn: phần tử nhóm cột <colgroup> và phần tử con duy nhất của phần tử này, 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 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 mọi dữ liệu bảng. Nếu các cột này trải dài trên nhiều cột, hãy sử dụng thuộc tính span.

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

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

Cả <colgroup><col> đều không có ý nghĩa ngữ nghĩa về việc giúp bảng dễ tiếp cận hơn, nhưng chúng cho phép tạo 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> được 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 bộ chọn như tr > *:nth-child(8) (chọn phần tử con thứ 8 của mỗi hàng) sẽ làm nổi bật toàn bộ cột thứ 8 hoặc sẽ làm nổi bật cột thứ 8 cho một số hàng, nhưng với một số ô cột thứ 9 và 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à bằng bộ chọn phức tạp bao gồm bộ chọn quan hệ :has().

Kết xuất theo lớp của các phần tử 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ẽ nằm ở 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 cùng và ở trên cùng, như minh hoạ trong sơ đồ của các lớp bảng. Các phần tử <td><th> không phải là phần tử con của phần tử <colgroup> hoặc <col> và không kế thừa kiểu của các phần tử đó.

Để tạo dải cho 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àu đen mờ vào mỗi hàng lẻ trong phần 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, bảng không thích ứng. Thay vào đó, các nút này được định cỡ theo nội dung theo mặc định. 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 ARIA role. Mặc dù có vẻ thừa thãi, nhưng thuộc tính display CSS có thể ảnh hưởng đến cây hỗ trợ tiếp cận trong một số trình duyệt.

Trình bày dữ liệu

Các phần tử bảng có ý nghĩa ngữ nghĩa mà các công nghệ hỗ trợ sử dụng để cho phép di chuyển qua các hàng và cột mà không bị "mất". Không nên sử dụng phần tử <table> để trình bày. Nếu bạn cần một 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 theo lưới, hãy sử dụng lưới CSS. Chỉ sử dụng bảng cho dữ liệu. Hãy suy nghĩ theo cách này: nếu dữ liệu của bạn cần có bảng tính để 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, có thể bạn cần có danh sách mô tả.

Nếu bạn không trình bày dữ liệu dạng bảng, đừng sử dụng <table>. Nếu bạn sử 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 điều này là không cần thiết. Tuy nhiên, bạn cần phải biết về biểu mẫu HTML, vì vậy, chúng ta sẽ đề cập đến vấn đề đó trong phần tiếp theo.

Kiểm tra mức độ hiểu biết

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 đề?

<caption>
<header>
<th>

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ả về các thuật ngữ đó.
Nguyên liệu cho một công thức nấu ăn.
Một bảng tính chứa thông tin chi tiết về học viên và điểm của họ trong 3 học kỳ.