Tagi HTML: tr

8 min. czytania

Witaj na moim blogu poświęconym programowaniu w HTML, CSS i JavaScript! Dziś zanurzymy się w świat tabel HTML, a konkretnie w element <tr>, który jest kluczowym budulcem każdej tabeli.

W tym przewodniku poznasz definicję, strukturę, konteksty użycia, atrybuty, stylizację w CSS i praktyczne integracje z JavaScript – wraz z kodami gotowymi do skopiowania.

Co to jest element <tr> i do czego służy?

Element <tr> (table row) reprezentuje jeden wiersz tabeli HTML. To podstawowy element strukturalny, który organizuje dane w rzędach wewnątrz <table>. To on definiuje poziome linie, w których umieszczasz komórki danych (<td>) lub nagłówki (<th>).

<tr> ma domyślnie display: table-row, a przeglądarki dziedziczą dla niego m.in. vertical-align i border-color od rodzica.

Dlaczego <tr> jest ważny? Tabele są idealne do prezentacji danych tabelarycznych – list produktów, wyników, harmonogramów czy raportów finansowych. Nie używaj tabel do layoutów – do tego służą Flexbox i CSS Grid.

Poprawna struktura i konteksty użycia elementu <tr>

Dziecko elementów <thead>, <tbody> lub <tfoot> – to najczęstszy i zalecany wzorzec. <thead> zawiera nagłówki, <tbody> treść tabeli, a <tfoot> stopkę (np. sumy).

Bezpośrednio w <table> – dopuszczalne tylko po <caption> i <colgroup> oraz potencjalnym <thead>, gdy brakuje <tbody>. W przeciwnym razie przeglądarka może błędnie zinterpretować strukturę.

Kontekst wewnętrzny: <tr> zawiera zero lub więcej elementów <td> (dane), <th> (nagłówki) lub zawartość skryptową (np. <script>).

Podstawowa składnia wygląda tak:

<tr>zawartość</tr>

Tag otwierający jest wymagany. Tag zamykający </tr> można pominąć tylko wtedy, gdy po nim następuje kolejny <tr> lub koniec elementu rodzica – w praktyce zalecam zawsze jawnie zamykać.

Przykładowy kod: podstawowa tabela z <tr> w <tbody>

Poniżej znajdziesz minimalny przykład z danymi w <tbody>:

<table>
<tbody>
<tr>
<th>Szafa</th>
<td>10 szt.</td>
</tr>
<tr>
<th>Stół</th>
<td>5 szt.</td>
</tr>
</tbody>
</table>

To tworzy tabelę z dwoma wierszami: nagłówki po lewej i dane po prawej.

Przykładowy kod: stopka tabeli z <tfoot>

Stopki świetnie nadają się do podsumowań i sum kontrolnych:

<table>
<tfoot>
<tr>
<th>Suma</th>
<td>15 szt.</td>
</tr>
</tfoot>
</table>

Przykładowy kod: <tr> bezpośrednio w <table> (bez <tbody>)

Gdy nie używasz <tbody>, <tr> może być bezpośrednim dzieckiem <table>:

<table>
<caption>Ilość przedmiotów w magazynie</caption>
<tr>
<th>Przedmiot</th>
<th>Ilość</th>
</tr>
<tr>
<th>Szafa</th>
<td>10</td>
</tr>
<tr>
<th>Stół</th>
<td>5</td>
</tr>
<tr>
<th>Suma</th>
<td>15</td>
</tr>
</table>

Atrybuty elementu <tr> – personalizacja wierszy

<tr> wspiera atrybuty globalne (np. id, class, style, data-*). Oto najczęściej używane i ich przykłady:

Atrybut Opis Przykład
class Klasa CSS do stylizacji (np. naprzemienne kolory wierszy). <tr class="row-even">
id Unikalny identyfikator do selekcji w JS lub CSS. <tr id="row1">
style Styl w linii (stosuj oszczędnie na rzecz klas). <tr style="background:#f0f0f0">
rowspan (w <td>/<th>) Scala komórkę w dół, wpływając na układ całego wiersza. <td rowspan="2">...</td>

Przykładowy wiersz wykorzystujący kilka atrybutów naraz:

<tr class="highlight" id="product-row-1" style="font-weight:bold">
<td>Produkt A</td>
<td>100 zł</td>
</tr>

Biblioteki jak Tailwind CSS ułatwiają stylizację klasami: <tr class="bg-gray-200 hover:bg-blue-100">.

Unikaj nadużywania atrybutu style – utrudnia to utrzymanie i skalowanie kodu. Zamiast tego stosuj klasy, preprocesory (Sass) lub CSS-in-JS.

Stylizacja <tr> za pomocą CSS

Domyślnie <tr> ma display: table-row; vertical-align: inherit; border-color: inherit;. Poniżej znajdziesz prosty CSS poprawiający czytelność tabeli:

tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #e0f7fa;
cursor: pointer;
}
tr th {
background-color: #4CAF50;
color: white;
}

Naprzemienne kolory wierszy, efekt hover i wyróżnione nagłówki znacząco poprawiają skanowalność danych.

Scalanie komórek w pionie realizujesz atrybutem rowspan na komórkach danych:

<tr>
<td rowspan="2">Scalony wiersz</td>
<td>Komórka 1</td>
</tr>
<tr>
<td>Komórka 2</td>
</tr>

Interakcja z <tr> w JavaScript

<tr> jest reprezentowany w DOM jako HTMLTableRowElement, dzięki czemu łatwo dynamicznie dodawać, modyfikować i usuwać wiersze. Oto prosty przykład dodawania wiersza:

<table id="moja-tabela">
<tbody></tbody>
</table>

<script>
const tbody = document.querySelector('#moja-tabela tbody');
const newRow = tbody.insertRow(); // Dodaje <tr>
newRow.insertCell(0).textContent = 'Nowy produkt';
newRow.insertCell(1).textContent = '50 zł';
newRow.classList.add('new-row');
</script>

Jeśli chcesz usuwać wiersze po kliknięciu, użyj zdarzeń na wszystkich <tr>:

document.querySelectorAll('tr').forEach(row => {
row.addEventListener('click', () => row.remove());
});

Takie mikrointerakcje świetnie sprawdzają się w interfejsach CRUD i panelach administracyjnych.

Najczęstsze błędy i najlepsze praktyki

Poniżej znajdziesz listę błędów i dobrych praktyk, które pomogą Ci uniknąć problemów w pracy z wierszami tabel:

  • błąd – umieszczanie <tr> poza <table> skutkuje niepoprawnym renderowaniem;
  • błąd – brak jawnego </tr> przy dodatkowej treści bywa źródłem trudnych do wykrycia anomalii;
  • praktyka – stosuj <thead>, <tbody> i <tfoot> dla lepszej dostępności i nawigacji screen readerów;
  • responsywność – na urządzeniach mobilnych dodaj overflow-x: auto do kontenera tabeli lub konwertuj widok na Flexbox/CSS Grid;
  • alternatywy – do budowy layoutów interfejsu używaj Flexbox i CSS Grid zamiast tabel.

Zaawansowane przykłady – pełna tabela z sumą i JS

Poniższy przykład pokazuje kompletną tabelę magazynową z CSS, JavaScript i dynamiczną sumą:

<!DOCTYPE html>
<html lang="pl">
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
tr:nth-child(even) { background-color: #f2f2f2; }
tr:hover { background-color: #f5f5f5; }
tfoot { font-weight: bold; }
</style>
</head>
<body>
<h3>Stan magazynu (2026)</h3>
<table>
<thead>
<tr>
<th>Przedmiot</th>
<th>Ilość</th>
</tr>
</thead>
<tbody>
<tr>
<th>Szafa</th>
<td>10</td>
</tr>
<tr>
<th>Stół</th>
<td>5</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Suma</th>
<td id="suma">15</td>
</tr>
</tfoot>
</table>

<button onclick="dodajWiersz()">Dodaj wiersz</button>

<script>
function dodajWiersz() {
const tbody = document.querySelector('tbody');
const row = tbody.insertRow();
row.innerHTML = '<th>Krzesło</th><td>3</td>';
aktualizujSume();
}

function aktualizujSume() {
let suma = 0;
document.querySelectorAll('tbody td').forEach(td => suma += parseInt(td.textContent, 10));
document.getElementById('suma').textContent = suma;
}

// Inicjalne przeliczenie po załadowaniu
aktualizujSume();
</script>
</body>
</html>

Kliknij przycisk, aby dodać nowy wiersz – suma zaktualizuje się automatycznie.