HTML I CSS · INF.03 · MODUŁ 04
Tabele
Tabela to nie sposób na układ strony, tylko narzędzie do danych. Nauczysz się go używać świadomie.
Wprowadzenie
Tabela w HTML służy do prezentowania danych w wierszach i kolumnach. Wiersz tworzy element <tr>, komórkę nagłówkową <th>, a zwykłą komórkę z danymi <td>. Całość zamykamy w elemencie <table>.
Dobra tabela ma tytuł w elemencie <caption> oraz podział na części: nagłówek <thead>, dane <tbody> i stopkę <tfoot>. Dzięki temu przeglądarka i czytnik ekranu wiedzą, gdzie kończy się opis kolumn, a zaczynają właściwe dane.
Nagłówek kolumny oznaczamy jako <th scope="col">, a nagłówek wiersza jako <th scope="row">. Atrybut scope mówi, do czego odnosi się dany nagłówek. To niewielki dodatek, który znacznie ułatwia odczyt tabeli osobom niewidzącym.
Tabela bywa mylona z narzędziem do układania całej strony. Współczesny HTML tego nie zaleca: od układu jest CSS, na przykład flexbox i grid. Tabelę zostawiamy tam, gdzie naprawdę mamy dane powiązane w wiersze i kolumny.
Jeżeli w komórkach znajdują się nagłówki sekcji, menu i obrazki bez związku z kolumnami, to znak, że tabela nie jest właściwym narzędziem. Do rozmieszczenia elementów użyj CSS.
Najważniejsza własność
Najważniejsza jest czytelna struktura: tytuł, nagłówek i właściwe dane. Tabela bez caption i bez poprawnych nagłówków wygląda dobrze tylko na obrazku — czytnik ekranu nie potrafi wtedy powiedzieć, co oznacza konkretna liczba.
<table>
<caption>Wyniki</caption>
<thead>
<tr>
<th scope="col">Imię</th>
<th scope="col">Punkty</th>
</tr>
</thead>
<tbody>
<tr><td>Ala</td><td>90</td></tr>
</tbody>
</table>
Tytuł, nagłówek kolumn i dane w osobnych grupach — każdy element ma swoje miejsce.
Do scalania komórek służą dwa atrybuty. colspan="2" łączy komórkę z sąsiednią komórką w poziomie, a rowspan="2" — w pionie. Wartość mówi, ile kolumn lub wierszy zajmuje komórka. Po scaleniu liczba elementów w wierszu może się zmniejszyć, ale siatka tabeli nadal musi się zgadzać.
| Element lub atrybut | Rola |
|---|---|
caption | Tytuł tabeli, umieszczany zaraz po otwarciu table. |
thead | Grupa wierszy z nagłówkami kolumn. |
tbody | Właściwe dane tabeli. |
tfoot | Stopka z podsumowaniem lub średnią. |
scope="col" | Nagłówek opisuje całą kolumnę. |
scope="row" | Nagłówek opisuje cały wiersz. |
colspan, rowspan | Scalanie komórek w poziomie i w pionie. |
Wygląd tabeli poprawiamy w CSS. border-collapse: collapse łączy sąsiednie obramowania komórek w jedną linię, padding daje odstęp między tekstem a krawędzią, a reguła nth-child(even) koloruje co drugi wiersz. Po najechaniu myszą wiersz może zmienić tło dzięki :hover.
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px 12px; border-bottom: 1px solid #e2e8f0; }
tbody tr:nth-child(even) { background: #f1f5f9; }
tbody tr:hover { background: #dbeafe; }
Tytuł tabeli i atrybuty scope nie są ozdobą. Dzięki nim czytnik ekranu potrafi powiązać nagłówek z właściwą komórką i odczytać na przykład „Punkty: 90” zamiast samej liczby.
Sprawdź, czy potrafisz policzyć komórki w tabeli ze scalaniem i czy dostrzeżesz błędy w gotowym kodzie.
Most: od teorii do kodu
Policz komórki i kolumny
Zanim napiszesz własną tabelę, prześledź, jak rowspan i colspan zmieniają liczbę komórek oraz zajęte kolumny.
Siatka tabeli ze scalaniem
śledzenie wartościUzupełnij obliczenia. Wpisz liczby: ile kolumn ma siatka, ile elementów td jest w całej tabeli i jak wyglądają poszczególne wiersze.
<table>
<tr>
<td rowspan="3">A</td>
<td>B</td>
<td colspan="2">C</td>
</tr>
<tr>
<td colspan="2">D</td>
<td>E</td>
</tr>
<tr>
<td>F</td>
<td>G</td>
<td>H</td>
</tr>
</table>
| Obliczenie | Wynik |
|---|---|
| Liczba kolumn siatki | |
Łączna liczba elementów td | |
| Własne komórki w wierszu 1 | |
| Własne komórki w wierszu 2 | |
| Kolumny zajęte przez wiersz 1 |
Siatka ma 4 kolumny. Komórka A zajmuje pierwszą kolumnę w trzech wierszach, dlatego w wierszu 2 są tylko dwie własne komórki: D (dwie kolumny) i E. Łącznie w tabeli jest 8 elementów td: A, B, C, D, E, F, G i H.
Znajdź błędy w tabeli
zaznaczanie błędówZaznacz dwie linie, w których jest błąd.
scope="kolumna"nie jest poprawną wartością. Powinno byćscope="col".colspanprzyjmuje liczbę całkowitą. Wartość"dwa"jest niepoprawna — powinno byćcolspan="2".
W linii 4 zła wartość scope, a w linii 7 wartość colspan nie jest liczbą. Obie pomyłki psują semantykę lub układ tabeli.
Przykłady
Budujemy prostą tabelę danych: tytuł, nagłówek kolumn, cztery wyniki i stopka ze średnią. Nagłówki mają atrybut scope="col".
<table>
<caption>Wyniki zawodów — bieg na 5 km</caption>
<thead>
<tr>
<th scope="col">Miejsce</th>
<th scope="col">Zawodnik</th>
<th scope="col">Czas</th>
</tr>
</thead>
<tbody>
<tr><td>1.</td><td>Anna Kowalska</td><td>21:14</td></tr>
<tr><td>2.</td><td>Marek Nowak</td><td>22:08</td></tr>
<tr><td>3.</td><td>Julia Zielińska</td><td>22:45</td></tr>
<tr><td>4.</td><td>Piotr Lewandowski</td><td>23:57</td></tr>
</tbody>
<tfoot>
<tr><td colspan="2">Średni czas</td><td>22:31</td></tr>
</tfoot>
</table>
table { width: 100%; border-collapse: collapse; }
caption {
margin-bottom: 10px;
font-size: 18px;
font-weight: 700;
text-align: left;
}
th, td {
border: 1px solid #cbd5e1;
padding: 9px 12px;
text-align: left;
}
thead th { background: #f1f5f9; }
tfoot td { background: #f8fafc; font-weight: 700; }
captionopisuje całą tabelę i jest pierwszym elementem w środku.theadzawiera nagłówki kolumn, atbodywłaściwe wyniki.tfootzamyka tabelę wierszem podsumowania, acolspan="2"łączy dwie komórki stopki.
Wynik: tabela ma logiczne części i czytelny nagłówek, więc można ją poprawnie odczytać także bez widzenia układu.
W planie lekcji jedna lekcja zajmuje dwa wiersze, a przerwa obiadowa rozciąga się na trzy kolumny. Do tego służą rowspan i colspan.
<table>
<caption>Plan lekcji — klasa 4 TI</caption>
<thead>
<tr>
<th scope="col">Godzina</th>
<th scope="col">Poniedziałek</th>
<th scope="col">Wtorek</th>
<th scope="col">Środa</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">8:00–8:45</th>
<td rowspan="2">Matematyka</td>
<td>Język polski</td>
<td>Fizyka</td>
</tr>
<tr>
<th scope="row">8:55–9:40</th>
<td>Historia</td>
<td>Chemia</td>
</tr>
<tr>
<th scope="row">9:50–10:35</th>
<td colspan="3">Przerwa obiadowa</td>
</tr>
<tr>
<th scope="row">10:45–11:30</th>
<td>Informatyka</td>
<td>Biologia</td>
<td>Matematyka</td>
</tr>
</tbody>
</table>
table { width: 100%; border-collapse: collapse; }
caption {
margin-bottom: 10px;
font-size: 18px;
font-weight: 700;
text-align: left;
}
th, td {
border: 1px solid #cbd5e1;
padding: 8px 10px;
text-align: left;
}
thead th { background: #e0e7ff; }
tbody th { background: #f8fafc; font-weight: 600; }
rowspan="2"sprawia, że Matematyka zajmuje miejsce w dwóch kolejnych wierszach.- W drugim wierszu nie powtarzamy tej komórki — jej miejsce jest już zajęte.
colspan="3"rozciąga przerwę obiadową na trzy kolumny dni.
Wynik: plan jest czytelny, a scalenia odpowiadają rzeczywistemu układowi zajęć.
Ten sam typ danych wygląda nowocześniej dzięki CSS: ciemny nagłówek, zebra i podświetlenie wiersza po najechaniu myszą.
<table>
<caption>Ranking kursów — semestr zimowy</caption>
<thead>
<tr>
<th scope="col">Miejsce</th>
<th scope="col">Kurs</th>
<th scope="col">Uczestnicy</th>
<th scope="col">Ocena</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>HTML i CSS</td><td>128</td><td>4,9</td></tr>
<tr><td>2</td><td>JavaScript</td><td>112</td><td>4,7</td></tr>
<tr><td>3</td><td>Bazy danych</td><td>96</td><td>4,6</td></tr>
<tr><td>4</td><td>PHP</td><td>84</td><td>4,4</td></tr>
<tr><td>5</td><td>Grafika</td><td>71</td><td>4,2</td></tr>
</tbody>
</table>
table { width: 100%; border-collapse: collapse; font-size: 15px; }
caption {
margin-bottom: 12px;
color: #0f172a;
font-size: 20px;
font-weight: 700;
text-align: left;
}
thead th {
padding: 12px 14px;
background: #1e293b;
color: #f8fafc;
font-size: 13px;
letter-spacing: .04em;
text-align: left;
text-transform: uppercase;
}
tbody td {
padding: 10px 14px;
border-bottom: 1px solid #e2e8f0;
}
tbody tr:nth-child(even) { background: #f1f5f9; }
tbody tr:hover { background: #dbeafe; }
tbody td:last-child { font-weight: 700; }
border-collapse: collapseusuwa podwójne linie między komórkami.nth-child(even)koloruje co drugi wiersz, tworząc tak zwaną zebrę.:hoverpodświetla wiersz pod kursorem, ale nie zmienia danych w tabeli.
Wynik: tabela jest czytelniejsza, a nagłówek i naprzemienne tło pomagają wzrokowi podążać za wierszem.
Przewidź układ tabeli
przewidywanieCo zobaczy użytkownik w drugim wierszu tabeli?
<table>
<tr>
<th scope="col">Produkt</th>
<th scope="col">Cena</th>
</tr>
<tr>
<td colspan="2">Brak danych</td>
</tr>
</table>
colspan="2" sprawia, że komórka „Brak danych” zajmuje miejsce obu kolumn. W wierszu jest więc jeden element td, który rozciąga się na całą szerokość tabeli.
Spróbuj samodzielnie
-
Zbuduj tabelę z trzema kolumnami: Imię, Klasa i Punkty. Dodaj tytuł „Wyniki klasy”, nagłówek kolumn z atrybutem
scope="col"oraz dwa wiersze danych.Pokaż rozwiązanie
Najpierw tytuł i nagłówek, potem dane w
tbody.<table> <caption>Wyniki klasy</caption> <thead> <tr> <th scope="col">Imię</th> <th scope="col">Klasa</th> <th scope="col">Punkty</th> </tr> </thead> <tbody> <tr><td>Ala</td><td>4 TI</td><td>90</td></tr> <tr><td>Jan</td><td>4 TI</td><td>75</td></tr> </tbody> </table>scope="col"mówi, że każdy nagłówek dotyczy kolumny poniżej, a nie całego wiersza. -
Przygotuj plan lekcji na jeden dzień. Kolumna Godzina ma trzy wiersze, lekcja „Informatyka” zajmuje dwa kolejne wiersze, a przerwa „Obiad” rozciąga się na wszystkie trzy kolumny dni. Użyj
rowspanicolspan.Pokaż rozwiązanie
Najpierw ustalamy siatkę: Godzina + trzy dni, czyli cztery kolumny. Informatyka zajmuje komórkę w dwóch wierszach, a obiad trzy kolumny dni.
<table> <caption>Plan lekcji — poniedziałek</caption> <thead> <tr> <th scope="col">Godzina</th> <th scope="col">Poniedziałek</th> <th scope="col">Wtorek</th> <th scope="col">Środa</th> </tr> </thead> <tbody> <tr> <th scope="row">8:00</th> <td rowspan="2">Informatyka</td> <td>Polski</td> <td>Fizyka</td> </tr> <tr> <th scope="row">9:00</th> <td>Historia</td> <td>Chemia</td> </tr> <tr> <th scope="row">10:00</th> <td colspan="3">Obiad</td> </tr> </tbody> </table>W drugim wierszu nie ma komórki Informatyki, bo jej miejsce jest już zajęte przez
rowspan="2". -
Uczeń napisał tabelę, ale zrobił cztery błędy. Wskaż je i popraw kod.
<table> <caption>Oceny</caption> <tr><th scope="kolumna">Imię</th><th>Ocena</th></tr> <tr><td colspan="dwa">Ala</td><td>5</td></tr> <tr><td>Jan</td></tr> </table>Pokaż rozwiązanie
Błędy:
scope="kolumna"zamiastscope="col", drugi nagłówek bezscope,colspan="dwa"zamiast liczby oraz wiersz Jana z tylko jedną komórką, mimo że tabela ma dwie kolumny.<table> <caption>Oceny</caption> <thead> <tr><th scope="col">Imię</th><th scope="col">Ocena</th></tr> </thead> <tbody> <tr><td>Ala</td><td>5</td></tr> <tr><td>Jan</td><td>4</td></tr> </tbody> </table>Każdy wiersz musi mieć tyle komórek, ile wynika z siatki tabeli. Scalanie nie zwalnia z pilnowania liczby kolumn.
-
Wystylizuj tabelę: dodaj
border-collapse: collapse, padding 10 px w komórkach, ciemny nagłówek, zebrę dla parzystych wierszy i zmianę tła po najechaniu myszą.Pokaż rozwiązanie
Styl tabeli trzymamy w CSS. Kolejność reguł nie jest sztywna, ale warto najpierw ustawić układ, potem kolory.
table { width: 100%; border-collapse: collapse; } th, td { padding: 10px 12px; border-bottom: 1px solid #e2e8f0; text-align: left; } thead th { background: #1e293b; color: #fff; } tbody tr:nth-child(even) { background: #f1f5f9; } tbody tr:hover { background: #dbeafe; }border-collapsełączy linie,nth-child(even)daje zebrę, a:hoverreaguje na najechanie kursorem. Nie zmieniają one struktury HTML.
Tabela jest dobra wtedy, gdy ma tytuł, logiczny nagłówek i dane w komórkach. Pamiętaj o scope oraz o tym, że colspan i rowspan zmieniają siatkę. Wygląd zostaw CSS — on odpowiada za obramowania, padding, zebrę i efekt najechania.