Урок · HTML
Таблицы HTML: строки и столбцы
HTML-таблица — тег <table> со строками <tr>, в которых стоят ячейки: заголовочные <th> и обычные <td>. Таблицы нужны для данных, которые читаются по строкам и столбцам: расписание, цены, сравнение тарифов. Для раскладки страницы их не используют — для этого есть Grid и Flexbox.
tr— строка,th— заголовок,td— ячейка данных.captionназывает таблицу,thead/tbodyразделяют шапку и данные.scope="col"иscope="row"связывают заголовки с данными для скринридера.colspanиrowspanобъединяют ячейки — используй умеренно.- Широкую таблицу на телефоне оборачивают в блок с
overflow-x: auto.
Зачем этот урок сейчас
Расписание занятий, сравнение тарифов, характеристики товара — данные, которые человек сравнивает по строкам и столбцам. Правильно размеченная таблица читается глазами, понятна скринридеру, а поисковики и ИИ-ассистенты охотно берут таблицы для быстрых ответов.
Основная структура
<table>
<caption>План обучения</caption>
<thead>
<tr>
<th scope="col">Тема</th>
<th scope="col">Время</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">HTML</th>
<td>20 минут</td>
</tr>
<tr>
<th scope="row">CSS</th>
<td>25 минут</td>
</tr>
</tbody>
</table>caption — название всей таблицы, первым ребёнком table. thead содержит строку заголовков столбцов, tbody — данные. Первая ячейка строки — тоже заголовок (th scope="row"): так скринридер, читая «20 минут», назовёт и столбец «Время», и строку «HTML».
Теги таблицы
| Тег | Назначение |
|---|---|
table | сама таблица |
caption | название таблицы |
thead, tbody, tfoot | шапка, данные, итоговая строка |
tr | строка |
th | заголовочная ячейка |
td | ячейка с данными |
colgroup, col | общие стили для столбца |
scope: связь заголовков и данных
Зрячий человек связывает ячейку с заголовками взглядом. Скринридер делает это по разметке: scope="col" говорит, что заголовок относится к столбцу, scope="row" — к строке. В простых таблицах браузеры часто угадывают сами, но явный scope надёжнее. В сложных таблицах с многоуровневыми заголовками используют атрибуты id у th и headers у td.
Объединение ячеек: colspan и rowspan
<table>
<caption>Расписание</caption>
<tr><th scope="col">Время</th><th scope="col">Пн</th><th scope="col">Вт</th></tr>
<tr><th scope="row">10:00</th><td>HTML</td><td rowspan="2">Практикум</td></tr>
<tr><th scope="row">12:00</th><td>CSS</td></tr>
<tr><th scope="row">14:00</th><td colspan="2">Перерыв</td></tr>
</table>colspan="2" растягивает ячейку на два столбца, rowspan="2" — на две строки. Объединённая ячейка заменяет соседние, их в разметке уже не пишут. Если в строке не сходится число ячеек, почти всегда рядом с объединением есть лишний или пропущенный td. Сложные объединения трудно читать на телефоне и скринридером — иногда проще разбить данные на две таблицы.
Итоговая строка
<table>
<caption>Корзина</caption>
<thead><tr><th scope="col">Курс</th><th scope="col">Цена</th></tr></thead>
<tbody>
<tr><td>HTML</td><td class="num">0 ₽</td></tr>
<tr><td>CSS</td><td class="num">1 500 ₽</td></tr>
</tbody>
<tfoot><tr><th scope="row">Итого</th><td class="num">1 500 ₽</td></tr></tfoot>
</table>tfoot выделяет итоги. Числовые столбцы удобнее выравнивать по правому краю — разряды встают друг под другом.
Оформление таблицы
table { width: 100%; border-collapse: collapse; }
caption { text-align: left; font-weight: 700; margin-bottom: 8px; }
th, td { padding: 10px 12px; border-bottom: 1px solid #e5e7eb; text-align: left; }
thead th { background: #f8fafc; }
tbody tr:nth-child(even) { background: #fbfcfe; }
.num { text-align: right; font-variant-numeric: tabular-nums; }border-collapse: collapse склеивает соседние рамки в одну линию. Зебра через :nth-child(even) помогает не сбиться со строки, а tabular-nums делает цифры одной ширины, чтобы числа в столбце выравнивались.
Таблица на телефоне
<div class="table-scroll" role="region" aria-label="Расписание" tabindex="0">
<table>…</table>
</div>.table-scroll { overflow-x: auto; }
.table-scroll table { min-width: 640px; }Широкую таблицу не сжимают до нечитаемых колонок: её оборачивают в блок с горизонтальной прокруткой, и прокручивается только таблица, а не вся страница. tabindex="0" и подпись позволяют прокручивать её с клавиатуры. Превращать строки в карточки имеет смысл, только если столбцов мало и каждая строка самостоятельна.
Таблица — для данных, не для раскладки
Раньше сайты верстали таблицами: колонки, шапки, меню. Сейчас так не делают — таблица задаёт смысл «это данные», и скринридер начнёт объявлять «таблица, 3 столбца» вместо меню. Простая проверка: если убрать рамки и таблица перестанет читаться как таблица данных, значит, это была вёрстка. Колонки сайта собирают Grid и Flexbox.
table или CSS Grid
Табличные данные: заголовки столбцов, значения сравнивают по строкам. Расписание, цены, характеристики.
Раскладка страницы и карточек: визуальная сетка без смысла «таблица данных».
Частые ошибки
- Верстают таблицей раскладку страницы.
- Делают первую строку жирными td вместо заголовков th.
- Не добавляют caption, и непонятно, что за данные.
- Пишут лишние td рядом с объединёнными ячейками.
- Оставляют пустые ячейки без пояснения вместо «нет занятий» или «—».
Доступность
Доступная таблица — это caption с названием, заголовки th со scope, простая структура без лишних объединений и понятные значения в каждой ячейке. Скринридер позволяет перемещаться по таблице стрелками и озвучивает заголовки строки и столбца для каждой ячейки — но только если они размечены.
Поддержка браузерами
Все теги таблиц и атрибуты scope, colspan и rowspan работают во всех браузерах и скринридерах.
Практика
Собери расписание из четырёх уроков: название, уровень и длительность. Добавь caption, заголовки столбцов и строк со scope, итоговую строку с общей длительностью и обёртку для прокрутки на телефоне. Выровняй длительность по правому краю.
Показать решение
<div class="table-scroll" role="region" aria-label="Расписание уроков" tabindex="0">
<table>
<caption>Расписание уроков</caption>
<thead>
<tr><th scope="col">Урок</th><th scope="col">Уровень</th><th scope="col">Время</th></tr>
</thead>
<tbody>
<tr><th scope="row">HTML</th><td>Новичок</td><td class="num">20 мин</td></tr>
<tr><th scope="row">CSS</th><td>Новичок</td><td class="num">25 мин</td></tr>
<tr><th scope="row">Flexbox</th><td>Средний</td><td class="num">30 мин</td></tr>
<tr><th scope="row">JavaScript</th><td>Средний</td><td class="num">40 мин</td></tr>
</tbody>
<tfoot>
<tr><th scope="row" colspan="2">Итого</th><td class="num">115 мин</td></tr>
</tfoot>
</table>
</div>Частые вопросы
Чем th отличается от td?
th — заголовочная ячейка для столбца или строки, td — ячейка с данными. Браузер по умолчанию делает th жирным и по центру, а скринридер связывает его с данными.
Зачем нужен caption?
Он называет таблицу: зрячий видит заголовок, скринридер объявляет его при входе в таблицу.
Как объединить ячейки?
colspan — по горизонтали, rowspan — по вертикали. Объединённые соседние ячейки в разметке не пишут.
Можно ли верстать сайт таблицами?
Нет. Таблицы — для табличных данных. Раскладку страницы делают Grid и Flexbox.
Как сделать таблицу адаптивной?
Оберни её в блок с overflow-x: auto: на узком экране прокручивается только таблица, а данные остаются читаемыми.