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: autodo 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.