Jak zrobić tabelę w html – kod i przykłady

Tablica danych w HTML to najprostszy sposób na pokazanie uporządkowanych informacji w wierszach i kolumnach. Bez względu na to, czy chodzi o cennik, plan zajęć, czy zestawienie wyników – tabela HTML daje pełną kontrolę nad strukturą. Poniżej konkretny przewodnik: od zera do praktycznych przykładów, które można od razu skopiować do projektu. Kod pokazuje zarówno podstawy, jak i elementy, które faktycznie przydają się w codziennej pracy. Wszystko w wersji do samodzielnego użycia, bez zbędnej teorii.

Podstawowa struktura tabeli w HTML

Tabela w HTML składa się z kilku podstawowych znaczników: <table>, <tr>, <td> oraz <th>. W praktyce wygląda to jak prosta hierarchia: tabela → wiersze → komórki.

<table>
    <tr>
        <th>Kolumna 1</th>
        <th>Kolumna 2</th>
    </tr>
    <tr>
        <td>Wartość 1</td>
        <td>Wartość 2</td>
    </tr>
</table>

Znaczniki w skrócie:

  • <table> – kontener całej tabeli.
  • <tr> (table row) – pojedynczy wiersz tabeli.
  • <td> (table data) – zwykła komórka z danymi.
  • <th> (table header) – komórka nagłówkowa, domyślnie pogrubiona i wyśrodkowana.

Tekst w <th> jest traktowany przez czytniki ekranu jako nagłówek kolumny lub wiersza, co mocno poprawia dostępność tabeli.

Na początek wystarczy powyższy szkielet. Stylowanie (ramki, odstępy, kolory) warto dodać osobno, zamiast korzystać z przestarzałych atrybutów typu border bezpośrednio w znaczniku.

Tworzenie prostej tabeli krok po kroku

Najszybciej opanować tabele, tworząc konkretny przykład. Poniżej prosty cennik usług z trzema kolumnami i kilkoma wierszami.

  1. Najpierw struktura HTML dokumentu (w wersji minimalnej):
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Przykładowa tabela</title>
</head>
<body>

    <!-- Tabela pojawi się tutaj -->

</body>
</html>
  1. Wewnątrz <body> dodana zostaje tabela z nagłówkiem i trzema wierszami danych:
<table>
    <tr>
        <th>Usługa</th>
        <th>Czas trwania</th>
        <th>Cena</th>
    </tr>
    <tr>
        <td>Konsultacja online</td>
        <td>30 minut</td>
        <td>150 zł</td>
    </tr>
    <tr>
        <td>Audyt strony WWW</td>
        <td>2 godziny</td>
        <td>400 zł</td>
    </tr>
    <tr>
        <td>Szkolenie indywidualne</td>
        <td>3 godziny</td>
        <td>700 zł</td>
    </tr>
</table>

Taki kod da się od razu otworzyć w przeglądarce. Tabela będzie wyglądała surowo (bez ramek i kolorów), ale struktura jest poprawna i czytelna. Na tym etapie ważne jest, by każdy wiersz <tr> miał tę samą liczbę komórek – przynajmniej dopóki nie pojawi się potrzeba łączenia komórek.

Nagłówki, podpis i sekcje tabeli

Przy większych tabelach (np. raporty, statystyki) warto uporządkować strukturę, korzystając z <thead>, <tbody>, <tfoot> i <caption>. Pozwala to zarówno na lepszą semantykę, jak i łatwiejsze stylowanie.

Nagłówki kolumn i wierszy

Nagłówki nie muszą pojawiać się tylko w pierwszym wierszu. Często stosuje się nagłówki w pierwszej kolumnie, opisujące całe wiersze. Dzięki temu dane są czytelniejsze, a użytkownicy korzystający z czytników ekranu otrzymują pełne informacje kontekstowe.

<table>
    <thead>
        <tr>
            <th>Dzień</th>
            <th>Godzina</th>
            <th>Zajęcia</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Poniedziałek</th>
            <td>18:00</td>
            <td>Yoga</td>
        </tr>
        <tr>
            <th scope="row">Środa</th>
            <td>19:30</td>
            <td>Trening siłowy</td>
        </tr>
    </tbody>
</table>

Atrybut scope=”row” jasno określa, że dany nagłówek dotyczy całego wiersza. Analogicznie można użyć scope=”col” przy nagłówkach kolumn (w <thead>), co ułatwia pracę technologiom asystującym.

Podpis tabeli i sekcje <thead> / <tbody> / <tfoot>

Znacznik <caption> dodaje podpis do tabeli, który wyświetla się domyślnie nad nią. To lepsze rozwiązanie niż dodawanie tytułu tabeli zwykłym tekstem przed nią, bo podpis jest powiązany semantycznie z tabelą.

<table>
    <caption>Plan zajęć na tydzień</caption>
    <thead>
        <tr>
            <th>Dzień</th>
            <th>Godzina</th>
            <th>Zajęcia</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Poniedziałek</th>
            <td>18:00</td>
            <td>Yoga</td>
        </tr>
        <tr>
            <th scope="row">Środa</th>
            <td>19:30</td>
            <td>Trening siłowy</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td colspan="3">Obowiązuje od 01.03.2026 r.</td>
        </tr>
    </tfoot>
</table>

Sekcja <tfoot> dobrze sprawdza się przy tabelach z podsumowaniami (np. suma wartości, stopka raportu). Nawet jeśli wizualnie ma znaleźć się na dole, w kodzie HTML często umieszcza się ją przed <tbody>, żeby przeglądarka mogła szybciej wyrenderować strukturę – ale nie jest to obowiązkowe.

Sekcje <thead>, <tbody>, <tfoot> ułatwiają także stylowanie: można nadać inny kolor tła nagłówkom, inny wierszom z danymi i inny podsumowaniu, bez dodatkowych klas.

Stylowanie tabeli: obramowanie, odstępy i czytelność

Surowa tabela HTML bez stylów jest mało czytelna. W praktycznym projekcie od razu warto dorzucić podstawowe style: ramki, odstępy, wyrównanie. Najlepiej zrobić to w CSS, a nie w atrybutach HTML.

Obramowanie i siatka

Najprostszy wariant, który wygląda dobrze w większości projektów, to cienka, szara siatka i zlane obramowania. Poniżej kompletny przykład z prostym stylem.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Tabela stylowana</title>
    <style>
        table {
            width: 100%;
            border-collapse: collapse; /* zlanie obramowań */
        }
        th, td {
            border: 1px solid #ccc;
            padding: 8px 12px;
            text-align: left;
        }
        thead th {
            background-color: #f5f5f5;
        }
        tbody tr:nth-child(even) {
            background-color: #fafafa; /* pasiaste wiersze */
        }
    </style>
</head>
<body>

<table>
    <thead>
        <tr>
            <th>Produkt</th>
            <th>Ilość</th>
            <th>Cena</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Klawiatura</td>
            <td>2</td>
            <td>120 zł</td>
        </tr>
        <tr>
            <td>Mysz</td>
            <td>1</td>
            <td>60 zł</td>
        </tr>
    </tbody>
</table>

</body>
</html>

Kluczowy parametr to border-collapse: collapse;. Bez niego każda komórka ma własne obramowanie i tabela wygląda „podwójnie” obrysowana. Przy większej ilości danych pasiaste wiersze (nth-child(even)) znacząco poprawiają czytelność.

Odstępy, wyrównanie i formatowanie liczb

Odstępy w komórkach ustawia się przez padding. Mała różnica (np. 8–12 px) potrafi zdecydować o tym, czy tabela wygląda na dopracowaną, czy ściśniętą. Warto też zadbać o wyrównanie danych liczbowych do prawej strony lub do środka, szczególnie przy cenach czy ilościach.

<style>
    td.cena {
        text-align: right;
        font-weight: bold;
        white-space: nowrap; /* zapobiega łamaniu 1200 zł na dwie linie */
    }
    td.liczba {
        text-align: right;
    }
</style>

<table>
    <tr>
        <th>Produkt</th>
        <th>Ilość</th>
        <th>Cena</th>
    </tr>
    <tr>
        <td>Monitor</td>
        <td class="liczba">3</td>
        <td class="cena">1200 zł</td>
    </tr>
</table>

W praktycznych tabelach warto rozdzielać klasy według rodzaju danych (np. .cena, .liczba, .procent), zamiast nadawać style na podstawie pozycji kolumny. Dzięki temu zmiana kolejności kolumn nie wymaga poprawiania CSS.

Łączenie komórek: colspan i rowspan

W bardziej rozbudowanych tabelach często zachodzi potrzeba łączenia kilku kolumn lub wierszy w jedną komórkę. Służą do tego atrybuty colspan (poziomo) i rowspan (pionowo).

Przykład prostego nagłówka, który rozciąga się na dwie kolumny:

<table>
    <tr>
        <th rowspan="2">Miesiąc</th>
        <th colspan="2">Sprzedaż</th>
    </tr>
    <tr>
        <th>Online</th>
        <th>Stacjonarna</th>
    </tr>
    <tr>
        <th scope="row">Styczeń</th>
        <td>1200 zł</td>
        <td>800 zł</td>
    </tr>
</table>

W pierwszym wierszu nagłówkowym:

  • rowspan=”2″ przy „Miesiąc” łączy komórkę w pionie na dwa wiersze,
  • colspan=”2″ przy „Sprzedaż” łączy dwie kolumny w jedną szeroką komórkę.

Najczęstszy błąd przy korzystaniu z colspan i rowspan to gubienie liczby komórek w kolejnych wierszach. Przeglądarka spróbuje to naprawić po swojemu, ale efekt wizualny bywa mało przewidywalny. Najbezpieczniej po każdym większym łączeniu komórek chwilowo dodać obramowanie do tabeli i sprawdzić, czy siatka się zgadza.

Przy tabelach z dużą liczbą połączonych komórek warto naszkicować układ na kartce lub w prostym edytorze graficznym, zanim zacznie się pisać HTML – oszczędza to sporo czasu na późniejsze poprawki.

Responsywne tabele w praktyce

Klasyczna tabela z wieloma kolumnami źle znosi małe ekrany. Zamiast wciskać ją na siłę w szerokość telefonu, lepiej zastosować prosty trik: poziome przewijanie wewnątrz kontenera. To najszybsze i najbezpieczniejsze rozwiązanie dla tabel z dużą ilością danych.

Przewijana tabela na małych ekranach

Wariant bazowy polega na opakowaniu tabeli w <div> z włączonym przewijaniem w poziomie. Nie zmienia to struktury danych, więc tabela nadal jest poprawna semantycznie.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Responsywna tabela</title>
    <style>
        .tabela-wrap {
            width: 100%;
            overflow-x: auto;
        }
        table {
            border-collapse: collapse;
            min-width: 600px; /* zapobiega zgnieceniu kolumn */
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            white-space: nowrap;
        }
        thead th {
            background: #f0f0f0;
        }
    </style>
</head>
<body>

<div class="tabela-wrap">
    <table>
        <thead>
            <tr>
                <th>Data</th>
                <th>Klient</th>
                <th>Projekt</th>
                <th>Godziny</th>
                <th>Stawka</th>
                <th>Kwota</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>01.03.2026</td>
                <td>ABC Sp. z o.o.</td>
                <td>Strona WWW</td>
                <td>6</td>
                <td>200 zł</td>
                <td>1200 zł</td>
            </tr>
            <tr>
                <td>02.03.2026</td>
                <td>XYZ S.A.</td>
                <td>Aplikacja</td>
                <td>4</td>
                <td>250 zł</td>
                <td>1000 zł</td>
            </tr>
        </tbody>
    </table>
</div>

</body>
</html>

Na dużych ekranach tabela zachowuje się normalnie, na małych pojawia się poziomy pasek przewijania tylko dla tego jednego elementu. Rozwiązanie jest proste, nie wymaga JavaScriptu i działa dobrze nawet przy dużych zestawieniach.

Bardziej zaawansowane podejścia (przekształcanie tabel w „karty” na mobile, ukrywanie mniej ważnych kolumn) wymagają już indywidualnego projektowania layoutu i często JavaScriptu. Do większości praktycznych zastosowań w zupełności wystarcza jednak poziome przewijanie plus dobrze zaplanowane nagłówki.