Таблицу в HTML собирают из трёх тегов: контейнер <table>, строки <tr> и ячейки <td>. Для ячеек-заголовков вместо <td> ставят <th>. Таблица строится по строкам: сначала открываете строку, потом перечисляете её ячейки слева направо.
<table>
<tr>
<th>Модуль</th>
<th>Уроков</th>
</tr>
<tr>
<td>HTML</td>
<td>8</td>
</tr>
</table>
Названия тегов пришли из английского: tr означает table row, то есть строка таблицы, td расшифровывается как table data (ячейка с данными), th как table header (ячейка-заголовок). Если вы только начинаете, сначала прочитайте, что такое HTML и как устроены теги.
Ниже разбираем все теги таблицы, объединение ячеек через colspan и rowspan, оформление в CSS и ошибки, на которых спотыкаются новички. Каждый пример мы открыли в Chrome и прогнали через валидатор W3C. Вёрстку с проверкой домашних заданий преподавателем дают курсы из каталога по HTML.
Как сделать таблицу в HTML: пошагово

Порядок одинаковый для таблицы любого размера.
- Откройте контейнер
<table>. - Если у таблицы есть название, сразу после
<table>поставьте<caption>. - Первую строку с названиями столбцов оберните в
<thead>, а её ячейки сделайте через<th>. - Строки с данными положите в
<tbody>. Каждая строка начинается с<tr>, внутри идут ячейки<td>. - Проверьте, что в каждой строке одинаковое число ячеек.
- Закройте
</table>и задайте рамки и отступы в CSS.
Вот таблица по этим шагам: учебный план из трёх модулей с итогом в подвале.
<table>
<caption>Учебный план курса</caption>
<thead>
<tr><th>Модуль</th><th>Тема</th><th>Уроков</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>HTML</td><td>8</td></tr>
<tr><td>2</td><td>CSS</td><td>12</td></tr>
<tr><td>3</td><td>JavaScript</td><td>15</td></tr>
</tbody>
<tfoot>
<tr><td colspan="2">Всего</td><td>35</td></tr>
</tfoot>
</table>
Без CSS браузер не рисует у таблицы ни одной линии. Ячейки просто встают в сетку с промежутком в пару пикселей, а заголовки выделены жирным.
%

%
Теги таблицы HTML и за что они отвечают
Обязательных тегов три: <table>, <tr> и <td>. Остальные описывают смысл частей таблицы, и без них её хуже понимают поисковики и программы экранного доступа.
| Тег | Что делает | Где стоит |
|---|---|---|
<table> |
создаёт таблицу | внешний контейнер |
<caption> |
подпись (название) таблицы | первым внутри table |
<colgroup>, <col> |
описывают столбцы, чтобы задать им ширину или фон | после caption, до строк |
<thead> |
шапка, строки с названиями столбцов | до tbody |
<tbody> |
тело таблицы с данными | после thead, групп может быть несколько |
<tfoot> |
подвал: итоги, примечания | последним, после tbody |
<tr> |
строка | внутри thead, tbody, tfoot или прямо в table |
<th> |
ячейка-заголовок | внутри tr |
<td> |
обычная ячейка с данными | внутри tr |
Порядок частей задан в спецификации HTML жёстко: caption, затем colgroup, thead, tbody или строки, и в самом конце tfoot. Отдельного тега для столбца с ячейками в HTML нет: столбец складывается из ячеек с одинаковым номером в разных строках.
Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединитьсяТег tr: строка таблицы
Строку таблицы задаёт тег <tr>. Внутри него разрешены только ячейки <td> и <th>, а ещё теги скриптов вроде <script> и <template>. Текст, картинку или ссылку кладут внутрь ячейки, а не прямо в строку.
В ячейке может стоять любая разметка: несколько абзацев, список, кнопка. Как устроены абзацы, мы разбирали в статье про тег p в HTML, а маркированные и нумерованные перечни в разборе тегов ul, ol и li.
Строку можно поставить прямо в <table>, без <tbody>. Мы проверили это в Chrome: браузер сам дописывает tbody вокруг таких строк. Это видно в инструментах разработчика, и это важно для CSS:
<!-- в коде -->
<table><tr><td>1</td></tr></table>
<!-- в DOM после загрузки -->
<table><tbody><tr><td>1</td></tr></tbody></table>
Отсюда частая загадка: селектор table > tr в CSS ничего не находит, хотя строки на месте. Между ними теперь стоит tbody, поэтому пишите table tr или tbody > tr.
У самого tr атрибутов почти нет. Старые align, valign, bgcolor и height браузеры пока понимают, но спецификация относит их к устаревшим, а валидатор на каждый выдаёт ошибку «… is obsolete. Use CSS instead». Цвет строки, высоту и выравнивание задают стилями.
Ячейки td и th: в чём разница
Обе создают ячейку, разница в смысле. <td> хранит данные, <th> подписывает столбец или строку. Программа экранного доступа зачитывает слепому пользователю заголовок перед значением ячейки. Без th она прочитает «35» и не скажет, что это число уроков.
Внешне браузер тоже их различает. Мы замерили стили по умолчанию в Chrome:
- в
<th>текст жирный и выровнен по центру; - в
<td>текст обычный и прижат к левому краю; - у обеих ячеек внутренний отступ 1 px, между ячейками промежуток 2 px.
Эти значения прописаны в таблице стилей браузера из спецификации, поэтому в Firefox и Safari картина та же.
Когда заголовки стоят и сверху, и в первом столбце, добавьте th атрибут scope. Значение col относит заголовок к столбцу, row к строке. Так советует и руководство W3C по доступным таблицам.
<tr>
<th scope="row">Понедельник</th>
<td>HTML</td>
<td>CSS</td>
</tr>
Шапка, тело и подвал: thead, tbody, tfoot и caption
Эти четыре тега делят таблицу на смысловые части. Таблица работает и без них, но с ними проще жить.
- Стили. Шапку красят селектором
thead th, и стиль не цепляет строки с данными. - Печать. Если длинная таблица уходит на несколько страниц, браузер повторяет thead вверху каждой страницы. Мы распечатали в PDF таблицу на 150 строк из Chrome: шапка стояла на всех четырёх листах.
- Скрипты. Новые строки добавляют в tbody, и шапка с итогом остаются на своих местах.
С tfoot связана ловушка из старых учебников. По правилам HTML 4 подвал писали до tbody, и в части статей так до сих пор и учат. Мы проверили такой порядок на валидаторе W3C: сейчас это ошибка «Element tbody not allowed as child of element table in this context». Подвал ставят последним, после tbody.
Подпись <caption> браузер выводит над таблицей по центру. Её место первым тегом внутри table: caption после строк валидатор тоже считает ошибкой.
Как объединить ячейки: colspan и rowspan

Ячейки в HTML объединяют двумя атрибутами, которые ставят td или th.
colspan="N"растягивает ячейку вправо на N столбцов.rowspan="N"растягивает ячейку вниз на N строк.
В текстовых редакторах ячейки объединяют кнопкой на панели, и таблица сама пересчитывает сетку. Если нужна таблица в документе, а не на сайте, смотрите наш разбор, как выровнять таблицу в Word. В HTML сетку пересчитываете вы.
Главное правило: ячейки, которые закрыла объединённая, в коде не пишут. Если ячейка в первой строке растянута на две строки вниз, во второй строке этого столбца уже занято, и ячеек там на одну меньше.
Пример ниже расписание на неделю. Практикум по HTML в понедельник занимает два занятия подряд, поэтому у него rowspan="2". Разбор домашних заданий идёт сразу во все три дня, у него colspan="3".
<table>
<caption>Расписание на неделю</caption>
<thead>
<tr>
<th>Время</th><th>Понедельник</th><th>Вторник</th><th>Среда</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">10:00</th>
<td rowspan="2">Практикум по HTML</td>
<td>CSS</td><td>JavaScript</td>
</tr>
<tr>
<th scope="row">12:00</th>
<td>Вёрстка макета</td><td>Git</td>
</tr>
<tr>
<th scope="row">14:00</th>
<td colspan="3">Разбор домашних заданий</td>
</tr>
</tbody>
</table>
Во второй строке три ячейки вместо четырёх: место понедельника занимает практикум из строки выше. В третьей строке две ячейки, потому что вторая занимает три столбца.
%

%
Есть и пределы. По спецификации colspan может быть от 1 до 1000, rowspan до 65 534. Мы задали в Chrome colspan="5000", и браузер молча урезал его до 1000. Значение rowspan="0" растягивает ячейку до конца своей группы строк, то есть до конца tbody.
Проверка перед сохранением: сложите в каждой строке ячейки с учётом colspan и тех, что сверху закрыл rowspan. Сумма в каждой строке должна совпасть с числом столбцов в шапке.
Как оформить таблицу через CSS
Рамки, отступы и цвета задают в CSS. Атрибут border="1" у table из старых примеров ещё работает, но валидатор помечает его как устаревший, а линии выходят объёмными, как в девяностые.
Минимальный набор, после которого таблица выглядит аккуратно:
table {
border-collapse: collapse; /* одна линия между ячейками вместо двойной */
width: 100%;
}
th, td {
border: 1px solid #d0d7de;
padding: 8px 12px;
text-align: left;
}
thead th {
background: #f3f4f6;
}
tbody tr:nth-child(even) {
background: #fafafa; /* «зебра»: каждая вторая строка */
}
tbody tr:hover {
background: #eef6ff; /* подсветка строки под курсором */
}
Самое заметное свойство здесь border-collapse: collapse. По умолчанию у каждой ячейки своя рамка, и между соседями получаются две линии с зазором. Свойство склеивает их в одну. Остальные свойства таблиц, от ширины столбцов до выравнивания чисел, проходят на курсах по CSS.
%

%
Как сделать таблицу адаптивной
Широкая таблица на телефоне вылезает за край экрана и тянет за собой всю страницу. Простое решение: обернуть её в блок с горизонтальной прокруткой.
<div style="overflow-x: auto;">
<table>...</table>
</div>
Таблица прокручивается пальцем внутри своего блока, а страница стоит на месте. Чтобы шапка не уезжала при вертикальной прокрутке длинной таблицы, ячейкам thead дают position: sticky; top: 0; и фон. Остальные приёмы под телефоны, от резиновых сеток до медиазапросов, описаны в статье о видах вёрстки.
Как добавить строку в таблицу через JavaScript
У таблиц в браузере есть свои методы: insertRow() добавляет строку, insertCell() добавляет в неё ячейку. Это короче, чем собирать элементы через createElement.
const tbody = document.querySelector('#plan tbody');
const row = tbody.insertRow(); // новая строка в конце tbody
row.insertCell().textContent = '2';
row.insertCell().textContent = 'CSS';
row.insertCell().textContent = '12';
Строки таблицы лежат в коллекции table.rows, ячейки строки в row.cells. Удалить строку можно методом row.remove(). Код мы запускали в Chrome на таблице учебного плана из начала статьи.
Когда таблица не нужна
Раньше на таблицах собирали весь макет сайта: шапку, колонки, подвал. Так верстали в конце девяностых и начале двухтысячных, и в коде старых сайтов это встречается до сих пор. Сегодня таблица нужна только для табличных данных: прайсов, расписаний, сравнений, результатов.
Макет страницы собирают на CSS Grid и Flexbox. Табличная вёрстка ломается на телефонах, а программы экранного доступа зачитывают такой макет как набор строк и ячеек. Отказаться от табличного макета стоит и ради поисковиков: им проще разобрать страницу, где таблица означает именно данные.
Обратный случай тоже бывает. Если данные по смыслу табличные, но разложены в div, читатель теряет связь «заголовок и значение». А для перечня без столбцов таблица избыточна, хватит обычного списка.
Частые ошибки в разметке таблиц

Каждую ошибку из списка мы воспроизвели и проверили валидатором W3C. В скобках его сообщение.
- Текст между ячейками. Слово, написанное прямо в tr или table, браузер выносит перед таблицей, и оно появляется над ней. Валидатор отмечает это ошибкой: «Misplaced non-space characters inside a table».
- Разное число ячеек в строках. Строка с лишней ячейкой торчит вправо, строка с недостающей обрывается. Валидатор пишет предупреждение «A table row was 3 columns wide and exceeded the column count established by the first row».
- Лишняя ячейка после rowspan. Ячейку, которую закрыла объединённая сверху, всё равно написали, и строка съехала на столбец.
- rowspan больше, чем строк в группе. Ячейка обрезается по краю tbody («Table cell spans past the end of its row group»).
- tfoot перед tbody или caption в конце. Правило из HTML 4 сейчас даёт ошибку, порядок частей описан выше.
- Оформление атрибутами.
bgcolor,align,widthу ячеек получают пометку «obsolete. Use CSS instead».
Если ячейка пустая, оставьте <td></td> без содержимого. Так столбец не сломается, а с border-collapse рамка у пустой ячейки тоже нарисуется.
Где освоить HTML и вёрстку системно
Таблицы, списки и абзацы относятся к первым темам курсов вёрстки. Следом идут сетки на Grid, адаптивность под телефоны и перенос макета из Figma в код. Как пройти этот путь до первой работы, мы расписали в статье как стать фронтенд-разработчиком. Чем занят на проекте верстальщик, рассказывает обзор профессии HTML-верстальщик.
Если удобнее учиться с наставником и проверкой заданий, вот курсы по HTML из нашего каталога:
| Курс | Школа | Стоимость со скидкой | В рассрочку | Длительность | Обзор курса от Checkroi |
|---|---|---|---|---|---|
| HTML и CSS с нуля Перейти на сайт курса | 91 626 ₽ | 7635 ₽/мес. | 11 месяцев | Обзор курса | |
| HTML и CSS. Адаптивная вёрстка и автоматизация Перейти на сайт курса | 23 400 ₽ | 3900 ₽/мес. | 2 месяца | Обзор курса | |
| Основы вёрстки HTML и CSS Перейти на сайт курса | 32 676 ₽ | 2723 ₽/мес. | 3 месяца | Обзор курса | |
| HTML и CSS с нуля | 195 160 ₽ | 7972 ₽/мес. | 12 месяцев | Обзор курса | |
| Frontend-разработчик: сайты на HTML/CSS/JavaScript Перейти на сайт курса | 9200 ₽ | - | 3 месяца | Обзор курса |
Больше программ — в полном каталоге курсов по HTML




