Tagi HTML: thead

9 min. czytania

Cześć! Jeśli kiedykolwiek budowałeś tabele w HTML i zastanawiałeś się, jak sprawić, by były nie tylko ładne wizualnie, ale też semantycznie poprawne i przyjazne dla czytników ekranu, to tag <thead> jest właśnie tym elementem, który robi różnicę. <thead> służy do grupowania nagłówka tabeli, czyli wierszy z tytułami kolumn, i zawsze powinien być używany w połączeniu z <tbody> (treść główna) oraz opcjonalnie <tfoot> (stopka).

W tym rozbudowanym wpisie o programowaniu w HTML/CSS/JavaScript przyjrzymy się tagowi <thead> od podszewki: od podstawowego zastosowania, przez zaawansowane style CSS, po przykłady z JavaScriptem i wskazówki dotyczące dostępności WCAG. Znajdziesz tu mnóstwo przykładowego kodu, który możesz skopiować i przetestować. Gotowy? Zaczynamy!

Po co w ogóle używać <thead>? Podstawy semantyki HTML

W czystym HTML bez strukturyzacji tabela to po prostu zbiór elementów <tr>, <th> i <td>. Ale nowoczesne tabele potrzebują semantyki – czyli informacji dla przeglądarek, robotów wyszukiwarek i programów do odczytu ekranu (np. NVDA czy VoiceOver), co jest nagłówkiem, a co danymi. <thead> definiuje sekcję nagłówkową tabeli, która zazwyczaj zawiera jeden lub więcej wierszy <tr> z komórkami nagłówkowymi <th>.

Oto najważniejsze zasady użycia <thead> zgodnie ze specyfikacją HTML5:

  • może być tylko jeden <thead> na <table>,
  • musi być umieszczony po <caption> i <colgroup>, ale przed <tbody>, <tfoot> lub luźnymi <tr>,
  • w środku musi znaleźć się co najmniej jeden element <tr>,
  • znacznik zamykający </thead> można pominąć, jeśli zaraz po nim następuje <tbody> lub <tfoot>.

Bez <thead> przeglądarka i czytniki ekranu nie mają pewności, że pierwszy wiersz to nagłówek – co oznacza gorszą dostępność i brak automatycznego powtarzania nagłówków przy drukowaniu. Obsługa <thead> jest pełna we wszystkich nowoczesnych przeglądarkach (Chrome, Firefox, Safari, Edge).

Prosty przykład: podstawowa tabela z <thead>

Oto klasyczny przykład tabeli z nagłówkiem, treścią i stopką – skopiuj i otwórz w przeglądarce:

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przykład tabeli z thead</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th scope="col">Miesiąc</th>
<th scope="col">Oszczędności</th>
</tr>
</thead>
<tbody>
<tr>
<td>Styczeń</td>
<td>100 zł</td>
</tr>
<tr>
<td>Luty</td>
<td>80 zł</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Suma</td>
<td>180 zł</td>
</tr>
</tfoot>
</table>
</body>
</html>

Rezultat: nagłówek jest wyraźnie oddzielony, a stopka zawsze na dole – nawet przy długich tabelach. To podstawa, ale zobaczmy, jak to ulepszyć CSS-em.

Stylizacja <thead> za pomocą CSS – kolory, wyrównanie i responsywność

Domyślne style dla <thead> to display: table-header-group; vertical-align: middle; border-color: inherit;. Możesz je nadpisać, by nagłówek wyróżniał się tłem, kolorem czy pozycjonowaniem. Pamiętaj, że lepki nagłówek wymaga przewijanego kontenera.

Przykład 1 – kolorowanie sekcji tabeli

Nadaj różny kolor każdej sekcji – zielony nagłówek, niebieskie ciało, czerwona stopka:

<!DOCTYPE html>
<html lang="pl">
<head>
<style>
table, th, td { border: 1px solid #000; border-collapse: collapse; }
thead { background-color: #4CAF50; color: #fff; }
tbody { background-color: #2196F3; color: #fff; }
tfoot { background-color: #f44336; color: #fff; }
</style>
</head>
<body>
<table style="width: 100%;">
<thead>
<tr>
<th scope="col">Miesiąc</th>
<th scope="col">Oszczędności</th>
</tr>
</thead>
<tbody>
<tr><td>Styczeń</td><td>100 zł</td></tr>
<tr><td>Luty</td><td>80 zł</td></tr>
</tbody>
<tfoot>
<tr><td>Suma</td><td>180 zł</td></tr>
</tfoot>
</table>
</body>
</html>

Efekt: przejrzysty, profesjonalny wygląd z wyraźnym podziałem sekcji.

Przykład 2 – wyrównanie tekstu i pionowe pozycjonowanie w <thead>

Użyj text-align i vertical-align bezpośrednio na <thead> lub wierszu <tr> – idealne dla wysokich nagłówków:

<table style="width: 100%; border: 1px solid #000; border-collapse: collapse;">
<thead style="text-align: left; vertical-align: bottom; height: 100px; background: linear-gradient(to bottom, #ddd, #fff);">
<tr>
<th scope="col">Miesiąc</th>
<th scope="col">Oszczędności (w zł)</th>
</tr>
</thead>
<tbody>
<tr><td>Styczeń</td><td>100</td></tr>
<tr><td>Luty</td><td>80</td></tr>
</tbody>
</table>

Nagłówek jest wyrównany do lewej i dołu komórki – czytelne przy większej wysokości wiersza.

Responsywna tabela z lepką <thead>

Aby uzyskać nagłówek, który „przykleja się” podczas przewijania, ustaw na komórkach nagłówka position: sticky i top: 0:

thead th {
position: sticky;
top: 0;
background: #4CAF50;
z-index: 10;
}

Dodaj overflow: auto; max-height: 300px; do kontenera otaczającego tabelę (np. do <div>), dzięki czemu nagłówek pozostanie widoczny przy przewijaniu danych w <tbody>.

Zaawansowane przykłady – JavaScript i interaktywne tabele

<thead> świetnie współpracuje z JS – np. do sortowania kolumn. Poniżej prosty przykład sortowania po kliknięciu w nagłówek kolumny:

Przykład: sortowalna tabela z <thead>

Skopiuj, wklej i przetestuj w przeglądarce:

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: #fff; cursor: pointer; user-select: none; }
th:hover { background-color: #45a049; }
</style>
</head>
<body>
<table id="tabela">
<thead>
<tr>
<th scope="col" data-type="text">Owoc</th>
<th scope="col" data-type="number">Cena (zł)</th>
</tr>
</thead>
<tbody>
<tr><td>Jabłko</td><td>2.50</td></tr>
<tr><td>Banany</td><td>4.00</td></tr>
<tr><td>Truskawka</td><td>12.00</td></tr>
</tbody>
</table>

<script>
(function () {
const tabela = document.getElementById('tabela');
const theadCells = tabela.querySelectorAll('thead th');
const tbody = tabela.querySelector('tbody');

theadCells.forEach((th, index) => {
th.addEventListener('click', () => {
const type = th.getAttribute('data-type') || 'text';
const dir = th.getAttribute('data-dir') === 'asc' ? 'desc' : 'asc';
th.setAttribute('data-dir', dir);

const rows = Array.from(tbody.querySelectorAll('tr'));
rows.sort((a, b) => {
let A = a.children[index].textContent.trim();
let B = b.children[index].textContent.trim();

if (type === 'number') {
A = parseFloat(A.replace(',', '.')) || 0;
B = parseFloat(B.replace(',', '.')) || 0;
} else {
A = A.toLowerCase();
B = B.toLowerCase();
}

if (A < B) return dir === 'asc' ? -1 : 1;
if (A > B) return dir === 'asc' ? 1 : -1;
return 0;
});

// odświeżenie DOM
rows.forEach(row => tbody.appendChild(row));
});
});
})();
</script>
</body>
</html>

Kliknij nagłówek, aby posortować rosnąco lub malejąco – <thead> ułatwia wiązanie zdarzeń z komórkami nagłówków.

Dostępność (WCAG) i najlepsze praktyki z <thead>

Według WCAG 2.1, semantyczna struktura tabel z <thead>, <tbody> i <tfoot> znacząco poprawia dostępność. Dodaj atrybut scope="col" do komórek nagłówka <th>, aby czytniki ekranu poprawnie kojarzyły komórki danych z nagłówkami kolumn. W większości przypadków nie ma potrzeby dodawania ról ARIA, jeśli używasz poprawnych znaczników HTML.

Najlepsze praktyki

Stosuj poniższe wskazówki, aby zachować czytelność i dostępność tabel:

  • używaj <th> zamiast <td> w <thead> dla prawidłowych nagłówków,
  • w prostych tabelach ogranicz się do jednego wiersza nagłówka (więcej stosuj tylko w złożonych strukturach),
  • dla danych zawsze łącz <thead> z <tbody> (i opcjonalnie <tfoot>),
  • unikaj tabel do układu strony – do layoutu używaj Flexbox lub CSS Grid.

Unikaj typowych błędów: nie umieszczaj <tbody> przed <thead>; nie zapominaj o lang="pl" w dokumencie, aby ułatwić pracę technologiom asystującym.