Potwierdzone sprawdzone punkt po punkcie · 2026-11-05
Pomiń nawigację
Informatyka · INF.03

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.

Tabela to dane, nie układ strony

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.

1. Który element zawiera tytuł tabeli?
1. Który element zawiera tytuł tabeli?
2. Do czego służy element thead?
2. Do czego służy element thead?
3. Do czego powinno się używać tabeli w HTML?
3. Do czego powinno się używać tabeli w HTML?

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.

Szkielet tabeli danych

<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 atrybutRola
captionTytuł tabeli, umieszczany zaraz po otwarciu table.
theadGrupa wierszy z nagłówkami kolumn.
tbodyWłaściwe dane tabeli.
tfootStopka z podsumowaniem lub średnią.
scope="col"Nagłówek opisuje całą kolumnę.
scope="row"Nagłówek opisuje cały wiersz.
colspan, rowspanScalanie 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.

CSS
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; }
Caption i scope to dostępność

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ści

Uzupeł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>
ObliczenieWynik
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

Znajdź błędy w tabeli

zaznaczanie błędów

Zaznacz dwie linie, w których jest błąd.

4. Który atrybut mówi, że nagłówek dotyczy kolumny?
4. Który atrybut mówi, że nagłówek dotyczy kolumny?
5. Co robi atrybut colspan="2" w komórce tabeli?
5. Co robi atrybut colspan="2" w komórce tabeli?
6. Jaki efekt daje reguła border-collapse: collapse?
6. Jaki efekt daje reguła border-collapse: collapse?

Przykłady

Przykład 1 — tabela wyników z nagłówkami

Budujemy prostą tabelę danych: tytuł, nagłówek kolumn, cztery wyniki i stopka ze średnią. Nagłówki mają atrybut scope="col".

HTML
<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>
CSS
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; }
Tabela wyników biegu z tytułem, nagłówkiem kolumn i wierszem średniego czasu
Efekt kodu: tytuł nad tabelą, wyraźny nagłówek kolumn i stopka ze średnią.
  1. caption opisuje całą tabelę i jest pierwszym elementem w środku.
  2. thead zawiera nagłówki kolumn, a tbody właściwe wyniki.
  3. tfoot zamyka tabelę wierszem podsumowania, a colspan="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.

Przykład 2 — plan lekcji ze scalaniem komórek

W planie lekcji jedna lekcja zajmuje dwa wiersze, a przerwa obiadowa rozciąga się na trzy kolumny. Do tego służą rowspan i colspan.

HTML
<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>
CSS
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; }
Plan lekcji, w którym komórka Matematyka zajmuje dwa wiersze, a przerwa obiadowa trzy kolumny
Efekt kodu: scalona komórka Matematyki przechodzi przez dwa wiersze, a przerwa obiadowa zajmuje całą szerokość dnia.
  1. rowspan="2" sprawia, że Matematyka zajmuje miejsce w dwóch kolejnych wierszach.
  2. W drugim wierszu nie powtarzamy tej komórki — jej miejsce jest już zajęte.
  3. colspan="3" rozciąga przerwę obiadową na trzy kolumny dni.

Wynik: plan jest czytelny, a scalenia odpowiadają rzeczywistemu układowi zajęć.

Przykład 3 — tabela ze stylami

Ten sam typ danych wygląda nowocześniej dzięki CSS: ciemny nagłówek, zebra i podświetlenie wiersza po najechaniu myszą.

HTML
<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>
CSS
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; }
Wystylizowana tabela rankingu z ciemnym nagłówkiem i naprzemiennym kolorem wierszy
Efekt kodu: ciemny nagłówek, naprzemienne tło wierszy i wyróżniona ostatnia kolumna. Po najechaniu myszą wiersz zmienia kolor na niebieski.
  1. border-collapse: collapse usuwa podwójne linie między komórkami.
  2. nth-child(even) koloruje co drugi wiersz, tworząc tak zwaną zebrę.
  3. :hover podś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

przewidywanie

Co 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>
7. Który element przechowuje wiersze z danymi tabeli?
7. Który element przechowuje wiersze z danymi tabeli?
8. Jaki efekt daje reguła tbody tr:nth-child(even) { background: #f1f5f9; }?
8. Jaki efekt daje reguła tbody tr:nth-child(even) { background: #f1f5f9; }?
9. Do czego służy element tfoot?
9. Do czego służy element tfoot?

Spróbuj samodzielnie

  1. 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.

  2. 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 rowspan i colspan.

    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".

  3. 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" zamiast scope="col", drugi nagłówek bez scope, 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.

  4. 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 :hover reaguje 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.

10. Który zapis poprawnie scala komórkę w pionie?
10. Który zapis poprawnie scala komórkę w pionie?
11. Po co w tabeli danych stosuje się atrybut scope?
11. Po co w tabeli danych stosuje się atrybut scope?
12. Dlaczego nie należy używać tabel do układu całej strony?
12. Dlaczego nie należy używać tabel do układu całej strony?