Таблицы
HTML-таблицы (
<table>) предназначены для представления табличных данных -- информации, организованной в строки и столбцы.
Зачем нужно
Таблицы -- единственный семантически правильный способ показать табличные данные: расписания, прайсы, сравнения, статистику. Screen readers используют структуру таблицы для навигации по ячейкам, а scope помогает связать данные с заголовками.
Где используется
- Расписания и графики
- Прайс-листы и сравнительные таблицы
- Отчёты и статистика
- Документация (справочники API, атрибутов)
- Не для layout -- для раскладки используй CSS Grid/Flexbox
Предпосылки
Базовая структура
<table>
<caption>Расписание занятий</caption>
<thead>
<tr>
<th scope="col">Время</th>
<th scope="col">Понедельник</th>
<th scope="col">Вторник</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">09:00</th>
<td>Математика</td>
<td>Физика</td>
</tr>
<tr>
<th scope="row">10:00</th>
<td>Химия</td>
<td>Информатика</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">Расписание на 1 семестр 2026</td>
</tr>
</tfoot>
</table>
Элементы таблицы
| Элемент | Назначение |
|---|---|
<table> |
Контейнер таблицы |
<caption> |
Заголовок/подпись таблицы |
<thead> |
Группа строк-заголовков |
<tbody> |
Группа строк основного содержимого |
<tfoot> |
Группа строк-итогов |
<tr> |
Строка таблицы (table row) |
<th> |
Ячейка-заголовок (table header) |
<td> |
Ячейка данных (table data) |
<col> |
Стилизация столбца |
<colgroup> |
Группировка столбцов |
<caption> -- заголовок таблицы
<table>
<caption>Таблица 1. Сравнение фреймворков</caption>
<!-- ... -->
</table>
<caption> должен быть первым потомком <table>. Screen readers читают его перед таблицей, давая контекст. Для SEO и a11y -- обязательный элемент.
<th> и атрибут scope
scope связывает заголовок с ячейками данных:
<table>
<thead>
<tr>
<!-- scope="col" -- заголовок столбца -->
<th scope="col">Фреймворк</th>
<th scope="col">Язык</th>
<th scope="col">Год</th>
</tr>
</thead>
<tbody>
<tr>
<!-- scope="row" -- заголовок строки -->
<th scope="row">React</th>
<td>JavaScript</td>
<td>2013</td>
</tr>
<tr>
<th scope="row">Vue</th>
<td>JavaScript</td>
<td>2014</td>
</tr>
</tbody>
</table>
Значение scope |
Что обозначает |
|---|---|
col |
Заголовок столбца |
row |
Заголовок строки |
colgroup |
Заголовок группы столбцов |
rowgroup |
Заголовок группы строк |
colspan и rowspan -- объединение ячеек
<table>
<caption>Расписание</caption>
<thead>
<tr>
<th scope="col">Время</th>
<th scope="col">Пн</th>
<th scope="col">Вт</th>
<th scope="col">Ср</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">09:00</th>
<!-- colspan: ячейка занимает 2 столбца -->
<td colspan="2">Лекция по HTML (Пн-Вт)</td>
<td>CSS</td>
</tr>
<tr>
<th scope="row">10:00</th>
<td>JavaScript</td>
<!-- rowspan: ячейка занимает 2 строки -->
<td rowspan="2">Практикум</td>
<td>TypeScript</td>
</tr>
<tr>
<th scope="row">11:00</th>
<td>React</td>
<!-- Вт занят rowspan сверху -->
<td>Node.js</td>
</tr>
</tbody>
</table>
<colgroup> и <col> -- стилизация столбцов
<table>
<caption>Бюджет</caption>
<colgroup>
<col>
<col span="2" class="income">
<col span="2" class="expense">
</colgroup>
<thead>
<tr>
<th scope="col">Месяц</th>
<th scope="col">Зарплата</th>
<th scope="col">Фриланс</th>
<th scope="col">Аренда</th>
<th scope="col">Еда</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Январь</th>
<td>100 000</td>
<td>30 000</td>
<td>40 000</td>
<td>25 000</td>
</tr>
</tbody>
</table>
<style>
.income { background: #e8f5e9; }
.expense { background: #ffebee; }
</style>
Адаптивные таблицы
Таблицы плохо помещаются на мобильных экранах. Решения:
Горизонтальная прокрутка
<div class="table-wrapper" role="region" aria-label="Таблица с прокруткой" tabindex="0">
<table>
<!-- широкая таблица -->
</table>
</div>
<style>
.table-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
</style>
Таблица как стек на мобильных
<style>
@media (max-width: 600px) {
table, thead, tbody, th, td, tr {
display: block;
}
thead { display: none; }
td {
padding-left: 50%;
position: relative;
}
td::before {
content: attr(data-label);
position: absolute;
left: 0.5rem;
font-weight: 700;
}
}
</style>
<table>
<thead>
<tr>
<th>Имя</th>
<th>Email</th>
<th>Роль</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Имя">Иван</td>
<td data-label="Email">ivan@example.com</td>
<td data-label="Роль">Разработчик</td>
</tr>
</tbody>
</table>
Стилизация таблицы
<style>
table {
width: 100%;
border-collapse: collapse; /* Убрать двойные границы */
font-family: system-ui, sans-serif;
}
th, td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid #e0e0e0;
}
th {
background: #f5f5f5;
font-weight: 600;
}
/* Зебра */
tbody tr:nth-child(even) {
background: #fafafa;
}
/* Ховер */
tbody tr:hover {
background: #e3f2fd;
}
caption {
caption-side: top;
text-align: left;
font-weight: 700;
padding: 0.5rem 0;
}
</style>
Частые ошибки
| Ошибка | Почему плохо | Как правильно |
|---|---|---|
| Таблица для layout | Нарушает семантику, плохо для a11y | CSS Grid / Flexbox для layout |
Нет <caption> |
Screen reader не знает, о чём таблица | Всегда добавляй <caption> |
Нет scope на <th> |
Screen reader не связывает данные с заголовками | scope="col" или scope="row" |
Нет <thead>/<tbody> |
Потеря семантики | Всегда разделяй на thead/tbody |
colspan/rowspan ошибка в подсчёте |
Таблица ломается | Считай ячейки в каждой строке |
| Нет адаптивности | Таблица выходит за экран | overflow-x: auto обёртка |
Практика
- Создай таблицу расписания с
<thead>,<tbody>,<tfoot>,<caption> - Добавь
scopeна все<th>и проверь через screen reader - Используй
colspanиrowspanдля объединения ячеек - Стилизуй таблицу: зебра, ховер,
border-collapse - Оберни таблицу в
<div>сoverflow-x: autoи проверь на мобильном
Связанные темы
- Семантика для screen readers -- навигация по таблицам
- ARIA атрибуты -- aria-описания для таблиц
- Списки -- альтернатива для простых перечислений