// htmltahak/ · 08 z 09

Tabulky

table, caption, thead, tbody, tfoot, tr, th, td, colgroup — tabulky pro tabulková data. NIKDY pro layout stránek!

// Struktura HTML tabulky — všechny elementy
<table>
<caption> — název tabulky
<thead> — záhlaví
<tr> — řádek
  <th scope="col"> — záhlavní buňka
<tbody> — tělo dat
<tr> — řádek
  <th scope="row"> — záhlaví řádku
  <td> — datová buňka
<tfoot> — zápatí
<tr><td colspan="N"> — souhrnný řádek
Ukázková tabulka — ceník
Produkt Cena Sklad
Victorinox Classic 299 Kč
Gerber Paraframe 549 Kč
Spyderco Delica 1 290 Kč
Celkem položek: 3 2 skladem
↑ živá ukázka výše generovaná HTML kódem na této stránce
// Zlaté pravidlo tabulek
✅ Tabulky PRO: Tabulková data — srovnání, ceníky, jízdní řády, rozvrhy, statistiky, výsledky, technické specifikace
❌ Tabulky NIKDY pro: Layout stránek, zarovnání textu, vícesloupcové rozvržení — to řešte CSS Flexbox nebo Grid
<table>

Tabulka

Kontejner pro tabulková data. Vždy s thead, th a scope pro přístupnost. NIKDY pro layout!

BLOCK

table je pro tabulková data — obsah který přirozeně tvoří mřížku řádků a sloupců. Screen readery čtou tabulky speciálně — oznamují záhlaví sloupce při každé buňce. Bez thead/th/scope je tabulka matoucí pro screen readery.

// Proč ne table pro layoutTabulkový layout byl standard v 90. letech před CSS. Problémy: pomalé renderování, nepřístupné (screen reader čte buňky jako data), neresponsivní, obtížná údržba. Dnes: CSS Grid nebo Flexbox.
Atributy
borderZastaralé — použijte CSS border-collapsedeprecated
Přístupnost tabulky — checklist
  • Vždy <caption> — název tabulky
  • Vždy <thead> se záhlavními buňkami
  • Vždy <th scope="col"> pro záhlaví sloupce
  • Pro záhlaví řádků: <th scope="row">
  • Responzivita: overflow-x: auto na obalovací div
Kompletní přístupná tabulka
HTML + CSS
<!-- Obalovací div pro responsivitu -->
<div style="overflow-x: auto">
  <table>
    <caption>Ceník produktů 2024</caption>

    <thead>
      <tr>
        <th scope="col">Produkt</th>
        <th scope="col">Cena</th>
        <th scope="col">Dostupnost</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <th scope="row">Victorinox Classic</th>
        <td>299 Kč</td>
        <td>Skladem</td>
      </tr>
      <tr>
        <th scope="row">Gerber Paraframe</th>
        <td>549 Kč</td>
        <td>Skladem</td>
      </tr>
    </tbody>

    <tfoot>
      <tr>
        <td colspan="3">
          Ceny jsou včetně DPH.
        </td>
      </tr>
    </tfoot>
  </table>
</div>

<!-- CSS pro tabulku -->
<style>
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
th, td {
  padding: 0.6rem 1rem;
  text-align: left;
  border-bottom: 1px solid #eee;
}
thead th {
  background: #f5f0ff;
  font-weight: 700;
  border-bottom: 2px solid #a78bfa;
}
tbody tr:hover { background: #fafafa; }
tbody tr:nth-child(even) {
  background: #f9f9f9;
}
tfoot td {
  font-size: 0.8rem;
  color: #666;
  border-top: 2px solid #eee;
}
caption {
  text-align: left;
  padding: 0.5rem 0;
  font-weight: 600;
  margin-bottom: 0.5rem;
}
</style>
<caption>

Název tabulky

Viditelný název tabulky — jako label. Musí být první child elementem uvnitř table.

BLOCK

caption je viditelný název tabulky — jako <label> pro formuláře. Screen readery ho přečtou jako první, ještě před samotnou tabulkou. Musí být první child element uvnitř table — před thead, tbody, tfoot.

// caption vs aria-labelcaption = viditelný název (preferováno). aria-label = neviditelný popis (pokud caption nelze použít). aria-labelledby = odkaz na jiný element jako název. Vždy preferujte viditelný caption.
Atributy
Žádné speciální atributy (jen globální)
CSS pozice
caption-side: topNad tabulkou (výchozí)default
caption-side: bottomPod tabulkouCSS
  • Musí být první child v table — před thead!
  • caption-side: bottom CSS pro pozici pod tabulkou
  • Alternativa: aria-label nebo aria-labelledby na table
  • Vždy přidejte — zásadní pro přístupnost
Příklad
HTML + CSS
<table>
  <!-- caption PRVNÍ, před thead! -->
  <caption>
    Měsíční tržby za Q1 2024
  </caption>
  <thead>...</thead>
  <tbody>...</tbody>
</table>

<!-- caption pod tabulkou -->
<table>
  <caption style="caption-side: bottom">
    Tabulka 1: Srovnání produktů
  </caption>
  ...
</table>

<!-- Alternativa bez caption -->
<table aria-label="Ceník produktů 2024">
  ...
</table>

<!-- CSS -->
<style>
caption {
  font-size: 0.875rem;
  font-weight: 700;
  text-align: left;
  padding: 0 0 0.5rem;
  color: #333;
}
</style>
<thead> <tbody> <tfoot>

Sekce tabulky

thead = záhlaví, tbody = data, tfoot = zápatí. Sémantické rozdělení pro přístupnost, tisk a výkon.

BLOCK

thead označuje záhlavní řádky (obsahuje th elementy). tbody obsahuje datové řádky. tfoot je zápatí — souhrnné řádky, poznámky. Prohlížeče mohou při tisku opakovat thead na každé stránce. tbody je povinný pro validní HTML5 — prohlížeč ho přidá automaticky, ale pište ho vždy explicitně.

// tfoot a pořadí v HTMLHistoricky byl tfoot v HTML před tbody — prohlížeče ho renderovaly dole. Dnes je doporučené pořadí: thead → tbody → tfoot. Prohlížeče zobrazí tfoot vždy dole bez ohledu na pořadí v HTML.
Kdy použít co
theadZáhlavní řádky — záhlaví sloupců
tbodyDatové řádky — samotná data
tfootSouhrnný řádek, celkem, poznámky, legenda
  • tbody je technicky povinný — vždy ho pište
  • Víc tbody = logické skupiny dat v tabulce
  • thead se při tisku opakuje na každé stránce
  • tfoot se zobrazí dole bez ohledu na pořadí v HTML
Příklad s více tbody skupinami
HTML
<table>
  <caption>Produkty podle kategorie</caption>

  <thead>
    <tr>
      <th scope="col">Název</th>
      <th scope="col">Cena</th>
    </tr>
  </thead>

  <!-- První skupina -->
  <tbody>
    <tr>
      <th scope="rowgroup"
        colspan="2">
        Victorinox
      </th>
    </tr>
    <tr>
      <th scope="row">Classic</th>
      <td>299 Kč</td>
    </tr>
    <tr>
      <th scope="row">Spartan</th>
      <td>499 Kč</td>
    </tr>
  </tbody>

  <!-- Druhá skupina -->
  <tbody>
    <tr>
      <th scope="rowgroup"
        colspan="2">
        Gerber
      </th>
    </tr>
    <tr>
      <th scope="row">Paraframe</th>
      <td>549 Kč</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <td>Celkem: 3 produkty</td>
      <td>od 299 Kč</td>
    </tr>
  </tfoot>
</table>
<tr>

Řádek tabulky

Obaluje buňky jednoho řádku. Přímí potomci mohou být jen th nebo td.

BLOCK

tr (table row) je řádek tabulky. Přímí potomci mohou být pouze <th> nebo <td> — nic jiného. tr patří do thead, tbody nebo tfoot.

// Zebra pruhy bez JSCSS :nth-child(even) na tr vytvoří zebra pruhy bez JS nebo přidávání tříd. tr:hover zvýrazní celý řádek. Obojí výrazně zlepší čitelnost dat v tabulce.
Atributy
Žádné speciální (dříve bgcolor, align — dnes CSS)
  • Přímí potomci jen th nebo td
  • CSS zebra: tr:nth-child(even) { background: #f9f9f9; }
  • Hover celého řádku: tr:hover { background: #f0f0f0; }
  • Klikatelný řádek: JS onclick na tr
CSS pro tr
CSS
/* Zebra pruhy */
tbody tr:nth-child(even) {
  background: #f9f9f9;
}

/* Hover zvýraznění */
tbody tr:hover {
  background: #f0ebff;
  cursor: pointer;
}

/* Aktivní / vybraný řádek */
tbody tr.selected {
  background: #ede9fe;
  outline: 2px solid #a78bfa;
}

/* Klikatelný řádek */
tbody tr[onclick] {
  cursor: pointer;
}
tbody tr[onclick]:hover {
  background: #f5f0ff;
}
<th>

Záhlavní buňka

Záhlaví sloupce nebo řádku. scope="col/row" povinné pro přístupnost. Tučný a centrovaný by default.

BLOCK

th (table header) je záhlavní buňka. scope="col" označí záhlaví sloupce, scope="row" záhlaví řádku. Screen reader řekne "Cena: 299 Kč" — díky th + scope. Bez scope je tabulka matoucí pro screen readery.

// scope vs headers atributscope = jednoduchý a dostatečný pro většinu tabulek. headers atribut = pro komplexní sloučené tabulky s colspan/rowspan. headers="id1 id2" odkazuje na konkrétní th pomocí id. Složitější na implementaci, ale nutné pro komplexní tabulky.
Atributy
scopecol = záhlaví sloupce, row = záhlaví řádku, colgroup, rowgroupcol / row
colspanSloučit přes N sloupcůčíslo
rowspanSloučit přes N řádkůčíslo
abbrZkrácená verze záhlaví pro screen readerystring
idPro headers atribut na tdstring
  • scope="col" pro záhlaví sloupce (v thead)
  • scope="row" pro záhlaví řádku (v tbody)
  • abbr = zkrácená verze pro úzké sloupce
  • th je tučný a centrovaný by default (lze přebít CSS)
Příklad scope
HTML
<!-- Záhlaví sloupců -->
<thead>
  <tr>
    <th scope="col">Produkt</th>
    <th scope="col">Cena</th>
    <th scope="col"
      abbr="Dostupnost">
      Dostupnost na skladě
    </th>
  </tr>
</thead>

<!-- Záhlaví řádků -->
<tbody>
  <tr>
    <th scope="row">
      Victorinox Classic
    </th>
    <td>299 Kč</td>
    <td>✅</td>
  </tr>
</tbody>

<!-- Komplexní: headers -->
<thead>
  <tr>
    <th id="produkt">Produkt</th>
    <th id="cena">Cena</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td headers="produkt">
      Victorinox
    </td>
    <td headers="cena">
      299 Kč
    </td>
  </tr>
</tbody>
<th scope="col">Cena</th>
<td><strong>Cena</strong></td> jako záhlaví
<td>

Datová buňka

Buňka s daty. colspan = přes sloupce, rowspan = přes řádky. Jen v tbody nebo tfoot.

BLOCK

td (table data) obsahuje data. colspan sloučí buňku přes více sloupců. rowspan přes více řádků. Součty colspan a rowspan musí matematicky sedět — jinak tabulka vizuálně "praskne".

// Jak funguje colspan/rowspancolspan="2" = tato buňka zabere 2 sloupce → v tomtéž řádku jsou o 2 td méně. rowspan="3" = tato buňka zabere 3 řádky → v následujících 2 řádcích jsou o 1 td méně. Komplexní sloučení je nepřístupné — zvažte zjednodušení.
Atributy
colspanSloučit přes N sloupců (horizontálně)číslo
rowspanSloučit přes N řádků (vertikálně)číslo
headersID záhlavních buněk pro komplexní tabulkyid id2
  • Součty musí sedět — colspan/rowspan matematika
  • Komplexní sloučení = nepřístupné, zvažte zjednodušení
  • Prázdná buňka: <td>&nbsp;</td> nebo <td></td>
  • headers atribut pro přístupnost sloučených buněk
Vizualizace colspan a rowspan
colspan a rowspan demo
ABCD
colspan="2" (A+B) rowspan="2" (C řádky 1+2) D1
A2 B2 D2
A3 B3 C3 D3
Příklad kódu
HTML
<!-- colspan: sloučení sloupců -->
<tr>
  <td colspan="3">
    Sloučeno přes 3 sloupce
  </td>
  <!-- tady jsou jen 1 td místo 3 -->
</tr>

<!-- rowspan: sloučení řádků -->
<tr>
  <td rowspan="2">Přes 2 řádky</td>
  <td>Normální buňka</td>
</tr>
<tr>
  <!-- první td chybí = sloučeno výše -->
  <td>Normální buňka</td>
</tr>

<!-- Prázdná buňka -->
<td></td>
<!-- nebo -->
<td>&nbsp;</td>
<colgroup> & <col>

Skupiny sloupců

Stylování celých sloupců najednou pomocí CSS. colgroup obaluje col elementy.

BLOCK

colgroup a col umožňují aplikovat CSS styly na celé sloupce najednou — bez nutnosti přidávat třídu na každou buňku. Musí být hned za caption a před thead. col je void element.

// Kdy colgroup použítChcete zvýraznit konkrétní sloupec (např. "Váš plán" v ceníku) — bez colgroup byste museli přidat třídu na každé td v sloupci. S col stačí jeden element. Pozor: col podporuje jen omezené CSS vlastnosti (background, width, border, visibility).
Atributy col
spanPočet sloupců, na které se col vztahuječíslo
CSS vlastnosti funkční na col
background / background-color width border visibility
  • colgroup musí být před thead, za caption
  • col je void element (nemá zavírací tag)
  • span="2" = col platí pro 2 sloupce
  • Jen omezené CSS vlastnosti fungují na col
Příklad — zvýraznění sloupce
HTML
<table>
  <caption>Ceník plánů</caption>

  <!-- colgroup PŘED thead -->
  <colgroup>
    <col>  <!-- 1. sloupec: název -->
    <col>  <!-- 2. sloupec: Basic -->
    <col class="highlighted">
           <!-- 3. sloupec: Pro (zvýrazněn) -->
    <col>  <!-- 4. sloupec: Enterprise -->
  </colgroup>

  <thead>
    <tr>
      <th scope="col">Funkce</th>
      <th scope="col">Basic</th>
      <th scope="col">Pro ⭐</th>
      <th scope="col">Enterprise</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Uživatelé</th>
      <td>1</td>
      <td>5</td>
      <td>Neomezeno</td>
    </tr>
  </tbody>
</table>

<!-- CSS -->
<style>
col.highlighted {
  background: #faf5ff;
}
/* Šířky sloupců */
col:first-child { width: 40%; }
col:not(:first-child) { width: 20%; }
</style>
← 07 Formuláře 08 / 09 — Tabulky 09 Skripty →