HTML & CSS

Списки та таблиці в HTML

Детальний розбір елементів <ul>, <ol>, <dl>, <table>, <caption>, <colgroup> за специфікацією HTML Living Standard: семантика, доступність, colspan/rowspan та коли використовувати таблиці.

Списки та таблиці в HTML

Чому структура важливіша за вигляд

Уявіть бібліотекаря, якому поставили завдання розставити книги. Є два підходи: перший каже «поставте ці книги на цю полицю», другий — «це серія детективів, вони мають стояти разом у алфавітному порядку». Другий підхід несе змісту більше, ніж перший.

Саме так працює семантика в HTML. Елементи <ul>, <ol>, <dl>, <table> — це не просто спосіб відобразити список чи сітку. Це спосіб передати значення браузеру, пошуковику та скринрідеру: «це перелік рівноцінних речей», «це послідовність кроків», «це структуровані дані з відношеннями між рядками і стовпцями».

Сьогодні розберемо ці елементи так, як їх визначає HTML Living Standard (WHATWG).


Ненумерований список — <ul>

Що каже специфікація

<ul> (unordered list — ненумерований список) представляє список елементів, порядок яких не є значущим. Зміна порядку елементів не впливає на зміст.

За специфікацією WHATWG:

  • Content model: нуль або більше елементів <li>, опційно з <script> та <template>
  • Permitted parents: будь-який елемент, що приймає flow content
🔒localhost:3000
Коли використовувати <ul>: коли елементи є рівноцінними і не мають чіткого порядку — навігаційні меню, списки тегів, переліки переваг, інгредієнти рецепту.

Вкладені списки

<ul> можна вкладати один в одного для ієрархічних структур. Важливо: вкладений список завжди знаходиться всередині <li>, а не після нього.

🔒localhost:3000

Нумерований список — <ol>

Що каже специфікація

<ol> (ordered list — нумерований список) представляє список елементів, порядок яких є значущим. Зміна порядку елементів змінює зміст.

Атрибути <ol>:

АтрибутТипОпис
startчислоПочаткове значення лічильника (за замовч. 1)
reversedбулевийЗворотний відлік
typeрядокТип маркера: 1, a, A, i, I
🔒localhost:3000

Атрибут value у <li>

Кожен <li> всередині <ol> може мати свій value, що змінює лічильник:

<ol>
    <li value="10">Десятий пункт</li>
    <li>Одинадцятий пункт</li>
    <!-- автоматично 11 -->
    <li value="20">Двадцятий пункт</li>
    <li>Двадцять перший пункт</li>
    <!-- автоматично 21 -->
</ol>
Коли використовувати <ol>: покрокові інструкції, рецепти (послідовність дій), рейтинги, юридичні документи, пронумеровані розділи — скрізь, де порядок несе змістовне навантаження.

Список визначень — <dl>, <dt>, <dd>

Що каже специфікація

<dl> (description list — список описів) представляє асоціативні пари: назва → опис. Це не просто «словник» — специфікація WHATWG описує <dl> як список груп, де кожна група містить:

  • Один або більше <dt> (description term — термін)
  • Один або більше <dd> (description definition — визначення)
🔒localhost:3000

Реальні застосування <dl>

<article>
    <h1>Огляд фреймворку Vue 3</h1>

    <dl>
        <dt>Автор</dt>
        <dd><a href="/authors/ivan-koval">Іван Коваль</a></dd>

        <dt>Опубліковано</dt>
        <dd><time datetime="2024-11-15">15 листопада 2024</time></dd>

        <dt>Категорія</dt>
        <dd><a href="/categories/frontend">Frontend</a></dd>

        <dt>Час читання</dt>
        <dd>8 хвилин</dd>
    </dl>
</article>
Типова помилка: використання <dl> для будь-яких пар «ключ-значення», навіть коли структура не є списком визначень. Якщо вміст — це просто два стовпці даних — вірніше використати <table>.

Таблиці — <table>

Коли таблиця є правильним вибором

Таблиця — не інструмент макетування. Це семантичний спосіб представлення табличних даних: інформації, яка має значущі відносини між рядками та стовпцями.

✅ Таблиці підходять для

  • Розклади (уроків, рейсів, сеансів)
  • Порівняльні характеристики продуктів
  • Фінансові звіти, тарифи
  • Статистика, результати змагань
  • Будь-які дані з чітким заголовком рядка/стовпця

❌ Таблиці НЕ підходять для

  • Верстка макету сторінки (header/sidebar/footer)
  • Вирівнювання форм
  • Відображення списків у кілька колонок
  • Будь-що, що можна зробити через CSS Grid або Flexbox

Базова структура таблиці

🔒localhost:3000

Але це лише мінімум. Специфікація WHATWG визначає значно багатшу модель.


Анатомія таблиці: всі елементи

<caption> — підпис таблиці

<caption>перший дочірній елемент <table>, що задає її назву. Доступний як для зрячих, так і для скринрідерів:

<table>
    <caption>
        Порівняння тарифних планів на хостинг
    </caption>
    <!-- ... -->
</table>
<caption> еквівалентний <figcaption> для зображень. Без нього таблиця може бути незрозумілою поза контекстом.

<thead>, <tbody>, <tfoot> — семантичне групування

Специфікація визначає три секції таблиці:

🔒localhost:3000

Навіщо розділяти <thead>/<tbody>/<tfoot>:

  • Браузер може прокручувати тіло таблиці незалежно, зберігаючи заголовки видимими
  • При друці заголовки та підвал повторюються на кожній сторінці
  • Скринрідери правильно визначають роль кожної секції

<th> vs <td> — заголовок vs дані

<th> (table header) — заголовкова комірка. <td> (table data) — комірка з даними.

Ключовий атрибут <th>scope:

scopeЗначення
colЗаголовок для всього стовпця
rowЗаголовок для всього рядка
colgroupЗаголовок для групи стовпців
rowgroupЗаголовок для групи рядків
<!-- scope="col" — заголовок стовпця -->
<thead>
    <tr>
        <th scope="col">Товар</th>
        <th scope="col">Ціна</th>
    </tr>
</thead>

<!-- scope="row" — заголовок рядка -->
<tbody>
    <tr>
        <th scope="row">Ноутбук Dell XPS 13</th>
        <td>42 000 грн</td>
    </tr>
</tbody>
Завжди вказуйте scope для <th>. Це вирішальний атрибут для доступності: скринрідер оголошує «Ціна: 42 000 грн» замість просто «42 000 грн».

<colgroup> та <col> — групування стовпців

<colgroup> (column group) та <col> (column) дозволяють стилізувати або ідентифікувати цілі стовпці без повторення атрибутів у кожній комірці.

🔒localhost:3000
<colgroup> та <col> — у першую чергу механізм для застосування CSS-стилів до цілого стовпця (через клас або атрибут style). Пряме стилізування через <col> підтримує лише обмежений набір CSS-властивостей: width, visibility, background, border.

colspan та rowspan — об'єднання комірок

colspan — об'єднання стовпців

🔒localhost:3000

rowspan — об'єднання рядків

🔒localhost:3000
colspan та rowspan роблять таблицю складнішою для скринрідерів. Якщо об'єднання комірок обов'язкове — завжди доповнюйте таблицю атрибутами scope, id/headers для правильної прив'язки.

Зв'язок через id та headers для складних таблиць

Для дуже складних таблиць (з багаторівневими заголовками) scope недостатньо. Використовують id + headers:

<table>
    <thead>
        <tr>
            <th id="city" scope="colgroup" colspan="2">Місто</th>
            <th id="temp" scope="colgroup" colspan="2">Температура (°C)</th>
        </tr>
        <tr>
            <th id="city-name" headers="city">Назва</th>
            <th id="city-region" headers="city">Регіон</th>
            <th id="temp-min" headers="temp">Мін.</th>
            <th id="temp-max" headers="temp">Макс.</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td headers="city city-name">Київ</td>
            <td headers="city city-region">Київська обл.</td>
            <td headers="temp temp-min">-15</td>
            <td headers="temp temp-max">+32</td>
        </tr>
    </tbody>
</table>

Атрибут <li>: елемент списку

<li> (list item) — елемент списку. Використовується всередині <ul>, <ol> та застарілого <menu>.

Атрибут value у <ol> (уже показаний вище) та відсутність атрибутів у <ul> — це вся специфіка <li>. Зверніть увагу: <li> як block-level елемент може містити будь-який flow content — параграфи, зображення, вкладені списки:

<ul>
    <li>
        <!-- <li> може містити блокові елементи -->
        <h3>JavaScript</h3>
        <p>Мова програмування для вебу.</p>
        <ul>
            <li>Node.js</li>
            <li>React</li>
            <li>Vue.js</li>
        </ul>
    </li>
</ul>

Підсумкові таблиці атрибутів

Атрибути <ol>

start
number
Початкове число лічильника. За замовчуванням 1. Завжди є цілим числом, навіть якщо type="a".
reversed
boolean
Відлік у зворотному порядку. Браузер відображає числа від start до 1 (або нижче).
type
string
Вибір маркера: 1 (числа), a (рядкові), A (великі), i (римські рядкові), I (римські великі).

Атрибути <li> в <ol>

value
number
Перевизначає поточне значення лічильника для цього елемента і всіх наступних.

Атрибути <table> та комірок

colspan
number
Кількість стовпців, що охоплює комірка (<td> або <th>). За замовч. 1.
rowspan
number
Кількість рядків, що охоплює комірка. За замовч. 1. Значення 0 — від поточного рядка до кінця секції (thead/tbody/tfoot).
scope
string
Для <th>: col, row, colgroup, rowgroup. Ключовий атрибут доступності.
headers
string
Список id заголовків, що відносяться до цієї комірки. Для складних таблиць з colspan/rowspan.
span
number
Атрибут <col> та <colgroup>: кількість стовпців, які охоплює ця колонка/група.

Практичні завдання


Комплексний приклад від А до Я

Тема: Розклад конференції DevUA 2024 — сторінка із програмою, спікерами та FAQ.

<!DOCTYPE html>
<html lang="uk">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta
            name="description"
            content="Програма конференції DevUA 2024: розклад доповідей, спікери, майстер-класи."
        />
        <title>Програма DevUA 2024</title>
    </head>
    <body>
        <header>
            <nav aria-label="Навігація по сторінці">
                <!-- <ul> для навігації — порядок не критичний -->
                <ul>
                    <li><a href="#schedule">Розклад</a></li>
                    <li><a href="#speakers">Спікери</a></li>
                    <li><a href="#workshops">Майстер-класи</a></li>
                    <li><a href="#faq">FAQ</a></li>
                </ul>
            </nav>
        </header>

        <main>
            <!-- ===== КЛЮЧОВІ ФАКТИ ===== -->
            <section aria-labelledby="facts-heading">
                <h2 id="facts-heading">Конференція в цифрах</h2>

                <!-- <dl> для пар параметр-значення -->
                <dl>
                    <dt>Дата</dt>
                    <dd><time datetime="2024-11-23">23–24 листопада 2024</time></dd>

                    <dt>Місце</dt>
                    <dd>UNIT.City, Київ</dd>

                    <dt>Кількість доповідей</dt>
                    <dd>42 доповіді від провідних спеціалістів</dd>

                    <dt>Треки</dt>
                    <dd>Frontend, Backend, DevOps, Architecture</dd>

                    <dt>Учасники</dt>
                    <dd>1200+ розробників</dd>

                    <dt>Мова</dt>
                    <dd>Українська, деякі доповіді — англійська</dd>
                </dl>
            </section>

            <!-- ===== РОЗКЛАД — ТАБЛИЦЯ ===== -->
            <section id="schedule" aria-labelledby="schedule-heading">
                <h2 id="schedule-heading">Розклад: День 1 (23 листопада)</h2>

                <table>
                    <caption>
                        Розклад доповідей першого дня конференції DevUA 2024. Зали: Main Stage, Frontend Track, Backend
                        Track.
                    </caption>

                    <colgroup>
                        <col />
                        <!-- Стовпець часу -->
                        <col span="3" />
                        <!-- Три зали -->
                    </colgroup>

                    <thead>
                        <tr>
                            <th scope="col">Час</th>
                            <th scope="col">Main Stage</th>
                            <th scope="col">Frontend Track</th>
                            <th scope="col">Backend Track</th>
                        </tr>
                    </thead>

                    <tbody>
                        <tr>
                            <th scope="row">09:00–09:30</th>
                            <!-- Реєстрація займає всі три зали -->
                            <td colspan="3">Реєстрація учасників та кава</td>
                        </tr>
                        <tr>
                            <th scope="row">09:30–10:15</th>
                            <!-- Відкриття — тільки Main Stage -->
                            <td colspan="3">Відкриття конференції — Вступне слово організаторів</td>
                        </tr>
                        <tr>
                            <th scope="row">10:30–11:15</th>
                            <td>State of Web 2024: куди рухається індустрія</td>
                            <td>Vue 3 Composition API: практичні патерни</td>
                            <td>PostgreSQL 17: нові можливості</td>
                        </tr>
                        <tr>
                            <th scope="row">11:30–12:15</th>
                            <td>AI у веб-розробці: реальні кейси</td>
                            <td>React Server Components у продакшні</td>
                            <td>Golang для highload: досвід Ukraine</td>
                        </tr>
                        <tr>
                            <th scope="row">12:15–13:15</th>
                            <!-- Обід займає всі зали -->
                            <td colspan="3">Обідня перерва та нетворкінг</td>
                        </tr>
                        <tr>
                            <!-- Воркшоп займає два часових слоти — rowspan="2" -->
                            <th scope="row" rowspan="2">13:15–15:30</th>
                            <td>Performance-аудит реального застосунку</td>
                            <!-- Воркшоп зайняв два слоти — rowspan -->
                            <td rowspan="2">Воркшоп: TypeScript від 0 до Pro (2 год.)</td>
                            <td rowspan="2">Воркшоп: Kubernetes для розробника (2 год.)</td>
                        </tr>
                        <tr>
                            <!-- Час вже є у попередньому рядку -->
                            <td>Web Assembly: практичний вступ</td>
                        </tr>
                        <tr>
                            <th scope="row">15:45–16:30</th>
                            <td>Micro-frontends: коли і як</td>
                            <td>CSS Container Queries: нова ера адаптивності</td>
                            <td>Event-driven architecture: від теорії до практики</td>
                        </tr>
                    </tbody>

                    <tfoot>
                        <tr>
                            <th scope="row">18:00–21:00</th>
                            <td colspan="3">After-party: нетворкінг, конкурси, DJ-сет</td>
                        </tr>
                    </tfoot>
                </table>
            </section>

            <!-- ===== СПІКЕРИ ===== -->
            <section id="speakers" aria-labelledby="speakers-heading">
                <h2 id="speakers-heading">Запрошені спікери</h2>

                <!-- <ul> — рівноцінний перелік без ієрархії -->
                <ul>
                    <li>
                        <article>
                            <h3>Олена Петренко</h3>
                            <!-- <dl> для метаданих спікера -->
                            <dl>
                                <dt>Компанія</dt>
                                <dd>Google, Staff Engineer</dd>

                                <dt>Доповідь</dt>
                                <dd>«Web Vitals 2025: метрики, що мають значення»</dd>

                                <dt>Час</dt>
                                <dd><time datetime="2024-11-23T10:30">10:30, 23 листопада</time></dd>
                            </dl>
                        </article>
                    </li>

                    <li>
                        <article>
                            <h3>Максим Ткаченко</h3>
                            <dl>
                                <dt>Компанія</dt>
                                <dd>Vercel, Engineering Manager</dd>

                                <dt>Доповідь</dt>
                                <dd>«React Server Components у продакшні: рік досвіду»</dd>

                                <dt>Час</dt>
                                <dd><time datetime="2024-11-23T11:30">11:30, 23 листопада</time></dd>
                            </dl>
                        </article>
                    </li>

                    <li>
                        <article>
                            <h3>Ірина Шевченко</h3>
                            <dl>
                                <dt>Компанія</dt>
                                <dd>Grammarly, Principal Engineer</dd>

                                <dt>Доповідь</dt>
                                <dd>«AI у веб-розробці: реальні кейси та підводні камені»</dd>

                                <dt>Час</dt>
                                <dd><time datetime="2024-11-23T11:30">11:30, 23 листопада</time></dd>
                            </dl>
                        </article>
                    </li>
                </ul>
            </section>

            <!-- ===== МАЙСТЕР-КЛАСИ ===== -->
            <section id="workshops" aria-labelledby="workshops-heading">
                <h2 id="workshops-heading">Майстер-класи</h2>

                <!-- <ol> — порядок важливий (за популярністю/рекомендацією) -->
                <ol>
                    <li>
                        <h3>TypeScript від 0 до Pro</h3>
                        <p>Ведучий: Андрій Мороз, Frontend Lead в Uklon</p>
                        <!-- Вкладений ol для програми воркшопу -->
                        <ol type="a">
                            <li>Базові типи та generics</li>
                            <li>Advanced types: утиліти та умовні типи</li>
                            <li>TypeScript у React: типізація пропсів, хуків, контексту</li>
                            <li>Налаштування TS у реальному проєкті</li>
                        </ol>
                    </li>

                    <li>
                        <h3>Kubernetes для розробника</h3>
                        <p>Ведучий: Сергій Лисенко, DevOps Engineer в EPAM</p>
                        <ol type="a">
                            <li>Основи K8s: поди, деплойменти, сервіси</li>
                            <li>Helm charts: пакетування застосунків</li>
                            <li>CI/CD пайплайни з GitHub Actions + K8s</li>
                        </ol>
                    </li>

                    <li>
                        <h3>Performance-аудит реального застосунку</h3>
                        <p>Ведуча: Наталія Ковальчук, Performance Engineer в Booking.com</p>
                        <ol type="a">
                            <li>Chrome DevTools: профілювання завантаження</li>
                            <li>Core Web Vitals: пошук та усунення проблем</li>
                            <li>Bundle analysis та оптимізація</li>
                        </ol>
                    </li>
                </ol>
            </section>

            <!-- ===== ПОРІВНЯЛЬНА ТАБЛИЦЯ КВИТКІВ ===== -->
            <section aria-labelledby="tickets-heading">
                <h2 id="tickets-heading">Квитки</h2>

                <table>
                    <caption>
                        Типи квитків DevUA 2024 та їх наповнення
                    </caption>

                    <thead>
                        <tr>
                            <th scope="col">Включено</th>
                            <th scope="col">Standard</th>
                            <th scope="col">Pro</th>
                            <th scope="col">VIP</th>
                        </tr>
                    </thead>

                    <tbody>
                        <tr>
                            <th scope="row">Доступ до всіх доповідей</th>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <tr>
                            <th scope="row">Запис доповідей (30 днів)</th>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <tr>
                            <th scope="row">Майстер-клас (1 на вибір)</th>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <tr>
                            <th scope="row">VIP-зона та нетворкінг зі спікерами</th>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <tr>
                            <th scope="row">After-party</th>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <tr>
                            <th scope="row">Сертифікат учасника</th>
                            <td>PDF</td>
                            <td>PDF + друкований</td>
                            <td>PDF + друкований</td>
                        </tr>
                    </tbody>

                    <tfoot>
                        <tr>
                            <th scope="row">Ціна</th>
                            <td>1 500 грн</td>
                            <td>3 500 грн</td>
                            <td>7 000 грн</td>
                        </tr>
                    </tfoot>
                </table>
            </section>

            <!-- ===== FAQ — список визначень ===== -->
            <section id="faq" aria-labelledby="faq-heading">
                <h2 id="faq-heading">Часті запитання</h2>

                <dl>
                    <dt>Чи будуть записи доповідей?</dt>
                    <dd>
                        Так, записи будуть доступні впродовж 30 днів після конференції для власників квитків Pro та VIP.
                    </dd>

                    <dt>Чи є знижки для студентів?</dt>
                    <dd>
                        Так, знижка 50% для студентів денної форми навчання за наявності студентського квитка.
                        Зв'яжіться з організаторами для отримання промокоду.
                    </dd>

                    <dt>Де знаходиться UNIT.City?</dt>
                    <dd>
                        UNIT.City — інноваційний парк у Києві за адресою: вул. Дорогожицька, 3. Найближча станція метро:
                        «Дорогожичі».
                    </dd>

                    <dt>Чи можна повернути квиток?</dt>
                    <dd>
                        Повернення можливе до 7 листопада 2024 включно з утриманням 10% комісії за обробку. Після цієї
                        дати повернення не здійснюється, але можна передати квиток іншій особі.
                    </dd>

                    <dt>Яка мова доповідей?</dt>
                    <dd>
                        Більшість доповідей — українською. Окремі міжнародні спікери — англійською. Перелік мов:
                        <!-- Вкладений список всередині <dd> — це коректно -->
                        <ul>
                            <li>Українська: 36 доповідей</li>
                            <li>Англійська: 6 доповідей (без перекладу)</li>
                        </ul>
                    </dd>
                </dl>
            </section>
        </main>

        <footer>
            <nav aria-label="Посилання підвалу">
                <ul>
                    <li><a href="/privacy">Політика конфіденційності</a></li>
                    <li><a href="/terms">Умови участі</a></li>
                    <li><a href="/contacts">Контакти організаторів</a></li>
                </ul>
            </nav>
            <p><small>&copy; 2024 DevUA Conference. Всі права захищені.</small></p>
        </footer>
    </body>
</html>

Що демонструє цей приклад:

📋 Списки

<ul> для навігації, спікерів, мов — де порядок не важливий. <ol> для воркшопів та програм — де порядок має значення. Вкладені <ul> та <ol> з коректним вкладенням всередині <li>.

📑 `<dl>`

Метадані конференції, характеристики спікерів, FAQ — асоціативні пари там, де вони є найприроднішою структурою. Вкладений <ul> всередині <dd>.

📊 Таблиці

<caption>, <colgroup>, <thead>/<tbody>/<tfoot>, scope="col/row", складний colspan та rowspan у розкладі та квитках.

🏗️ Архітектура

Кожен елемент на своєму місці: <dl><table><ul>. Семантична структура з правильними <section> та aria-labelledby.

Корисні посилання